之前在众多App上看到过骨架屏,不过今天才知道这个效果叫骨架屏hhh.
这个效果体验上比焦虑圈要好很多🚀
基础栗子: Base_demo
加载栗子: loading_demo
前言
今天刷视频的时候看到骨架屏对用户体验有显著的提升,边学边敲->Base_demo
后面对代码进行了少量的修改 -> loading_demo, 将代码和请求相结合。后期可以和懒加载配合使用。🚀🌙    
基础栗子
HTML结构
这里有两个div, 一个表示加载后的, 一个表示加载中的. 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | <div class="card">     <div class="image">         <img src="https://www.imagesource.com/wp-contentuploads/2019/06/Rio.jpg" alt="">     </div>     <div class="content">         <h4>Skeleton Demo</h4>         <div class="description">             骨架框效果测试样例,这是一段测试使用噶文字This is a test text.         </div>     </div> </div>
  <div class="card loading">     <div class="image"></div>     <div class="content">         <h4></h4>         <div class="description"></div>     </div> </div>
   | 
 
CSS
观察栗子可以发现,加载的时候背景有一道白色光影划过。这里利用了background的 linear-gradient函数,这是一种特别的image。表示渐变轴为100°, 从rgba(255, 255, 255, 0) 40% 渐变到 rgba(255, 255, 255, .5) 50%.
然后用background-size 将 linear-gradient图片宽拉伸一倍.
最后通过改变position来移动白色反光区域,造成光影特效.  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
   | :root{     --loading-grey: #ededed; } body{     background-color: #fefefe;     font-family: Arial, Helvetica, sans-serif;     font-size: 15px;     display: flex;     justify-content: space-evenly;     align-items: center;     min-height: 100vh; }
  .card{     width: 320px;     background-color: #fff;     border-radius: 6px;     overflow: hidden;     box-shadow: 0px 4px 6px rgba(0, 0, 0, .12); }
  .image{     height: 200px; }
  .image img{     display: block;     width: 100%;     height: inherit;     object-fit: cover; }
  .content{     padding: 2rem 1.8rem; }
  h4{     margin: 0 0 1rem;     font-size: 1.5rem;     line-height: 1.5rem; }
  .description {     font-size: 1rem;     line-height: 1.4rem; }
  .loading .image, .loading h4, .loading .description{     background-color: var(--loading-grey);     background: linear-gradient(         100deg,         rgba(255, 255, 255, 0) 40%,         rgba(255, 255, 255, .5) 50%,         rgba(255, 255, 255, 0) 60%     ) var(--loading-grey);     background-size: 200% 100%;     background-position-x: 120%;     animation: 1s loading ease-in-out infinite; }
  @keyframes loading{     to{         background-position-x: -20%;     } }
  .loading h4{     min-height: 1.6rem;     border-radius: 4px;     animation-delay: .05s; }
  .loading .description{     min-height: 4rem;     border-radius: 4px;     animation-delay: .06s; }
  | 
 
初步结束
到此为止,基本的效果已经实现了。-> Base_demo
稍微修改一下
修改了一下,将加载和加载后相结合.  
HTML结构
因为将加载和加载后结合起来, 这里取消了第二个div.   
1 2 3 4 5 6 7 8 9 10 11
   | <div id="Skeleton" class="card loading">     <div class="image">         <img id="img" src="https://www.imagesource.com/wp-content/uploads/2019/06/Rio.jpg" alt="">     </div>     <div class="content">         <h4>Skeleton Demo</h4>         <div class="description">                 骨架框效果测试样例,这是一段测试使用噶文字。This is a test text.         </div>     </div> </div>
   | 
 
CSS
沿用上面的css, 这里不再重复.   
JavaScript
这里用了onreadystatechange, 当页面加载完时readyState属性会是 complete来判断是否加载完资源,后期可以灵活更改。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | document.onreadystatechange = () => {     const Skeleton = document.querySelector("#Skeleton")     Skeleton.classList.add("loading")
      const text = document.querySelectorAll(".content h4")     text.forEach(e => { e.innerText = "" })
      const description = document.querySelectorAll(".description")     description.forEach(e => { e.innerText = "" })
      if (document.readyState == "complete") {         console.log(Skeleton.classList.remove("loading"))         text.forEach(e => { e.innerText = "Skeleton Demo" })         description.forEach(e => {             e.innerText = "骨架框效果测试样例,这是一段测试使用噶文字。This is a test text."         })     } }
  |