现在给网站做了一个load的加载效果,但是目前流行的应该是Skeleton Screen 骨架屏,这个原本是在苹果端app里制作的,然后有人自己移植到web端,常见h5架构页面,如饿了么、知乎、facebook、酷安,都有应用,那么我就很好奇了,到底是怎么做的,于是百度了一下。

了解Skeleton Screen 骨架屏

解释有下:

简单来说,骨架屏就是在页面内容未加载完成的时候,先使用一些图形进行占位,待内容加载完成之后再把它替换掉。

通过 puppeteer 在服务端操控 headless Chrome 打开开发中的需要生成骨架屏的页面,在等待页面加载,渲染完成之后,在保留页面布局样式的前提下,通过对页面中元素进行删减或增添,对已有元素通过层叠样 式进行覆盖,这样达到在不改变页面布局下,隐藏图片和文字,通过样式覆盖,使得其展示为灰色块。然后将修改后的 HTML 和 CSS 样式提取出来,这样就是骨架屏了.

那么从上面的解释中我们可以得知,其原理就是在加载之前就要生成骨架页面,骨架页面的原理其实就是在不改变页面布局的情况下,通过修改html和css将原有的内容进行隐藏覆盖,然后等待加载完毕后再将内容替换出来。

这样一想,就很简单了,依我个人之见是这样的:网页的初始状态就是骨架结构,用户打开就是骨架状态,当页面dom加载完毕后,就开始慢慢将骨架的样式隐去,显示出内容。

如图:

代码

我的想法是这样,因为你不可能去判断到每个元素的内容是否加载完毕,即便你给每个元素添加load事件,那么资源的损耗就和实际收入完全不成正比,所以我是在load事件完成后将所有的骨架慢慢消失,本来想通过计算透明度的方式来设置骨架消失的动效,但是经过这段时间的使用这种计算方法,发现非常消耗资源,为此我采用了业界常用的class方法。

首先给需要显示骨架的元素添加一个名为vu的class,这个class本身relative,然后创建他的伪类before,通过伪类的absolute浮动到最上层,然后添加背景层将该元素的内容遮盖。

此时已经达到了我预期的效果。

css

.vu {
    position: relative;
}
.vu::before {
    content: "";
    position: absolute;
    top: 0;bottom: 0;
    left: 0;right: 0;
    height: 100%;
    background-color: #eee;
    opacity: 1;
    transition: opacity 1s;
}
.nu::before {
    opacity: 0;
    
}

js

js部分我就判断,当load事件加载完毕——获取class名为vu的元素集合,for语句循环这个数组,给每个元素添加一个Timeout延迟运行,这样就可以达到骨架一个个慢慢消失而不是集体消失,然后我们使用的时候添加的是class=nu,所以在opacity的动画还未消失前,我们不能直接删除这个vu,为此又添加了一个延迟,在1s后删除,这样刚好在动画完毕后class也删除了,这样既不影响原来的布局也不会造成混乱,非常奈斯!

window.onload = function(){
    var vu = document.getElementsByClassName('vu')
    for(var i = 0;i<vu.length;i++) {
        var son = vu[i];
        setson(son);
    }
    function setson(son) {
        setTimeout(function(){
            addClass(son,'nu');
            setTimeout(function(){
                removeClass(son,'vu');
            },1000)
        },500)
    }
    
    function addClass(element,name) {
        if(!element.className.match(new RegExp('(^|\\s)'+name+'(\\s|$)'))) {
            element.className += ' ' + name;
        }
    }
    function removeClass(element,name) {
        if(element.className.match(new RegExp('(^|\\s)'+name+'(\\s|$)'))) {
            element.className = element.className.replace(new RegExp('(^|\\s)'+name+'(\\s|$)'),' ');
        }
    }
};

效果图+在线预览:

浏览地址点击

资源下载

本人也提供资源下载,有兴趣的可以自己下载使用,当然也是为了我以后忘记了还能再看看!

蓝奏云 密码:8lc9

分类: JavaScript 标签: 预加载Skeleton Screen骨架屏页面加载动画

评论

全部评论 9

  1. melody
    melody
    Google Chrome Windows 10
    假如1个页面只一个列表,整个列表都需要异步ajax,那这里的懒加载,只是一个动销吗,因为看示例,只有当页面有数据时,才能有元素,才能添加 vu 类
    1. 木灵鱼儿
      木灵鱼儿
      FireFox Windows 10
      @melody怎么说呢,这个东西就是一个占位,你可以将元素伪类作为遮罩,也可以做一个相似的遮罩元素展示,内容出来再隐藏,我这都是瞎琢磨,现在前后端分离占主力,大部分框架都有预设骨架效果,你可以看看,没必要自己研究了
      1. melody
        melody
        Google Chrome Windows 10
        @木灵鱼儿

        了解。
        by the way, cool website

        1. 木灵鱼儿
          木灵鱼儿
          FireFox Windows 10
          @melody客气了,如果你评论时留的qq邮箱啥的,其实可以收到评论回复提醒的[tv_doge]
          1. melody
            melody
            Google Chrome Windows 10
            @木灵鱼儿是留了邮箱的哈,只是我之前没注意[笑哭]
            1. 木灵鱼儿
              木灵鱼儿
              FireFox Windows 10
              @melody[tv_点赞]我都是用的qq邮箱
    2. melody
      melody
      Google Chrome Windows 10
      @melody动效
  2. 南楼月下
    南楼月下
    Google Chrome Windows 10
    实用处很大![tv_doge]
    1. 木灵鱼儿
      木灵鱼儿
      FireFox Windows 10
      @南楼月下[妙啊]现在很多框架都有这种效果,我还没研究他们是怎么做的

目录