木灵鱼儿

木灵鱼儿

阅读:3708

最后更新:2019/05/04/ 3:45:31

高仿Skeleton Screen 骨架屏

现在给网站做了一个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

版权申明

本文系作者 @木灵鱼儿 原创发布在木灵鱼儿 - 有梦就能远航站点。未经许可,禁止转载。

关于作者

站点职位 博主
获得点赞 0
文章被阅读 3708

相关文章