一、背景
用户体验一直是前端开发需要考虑的重要部分,在数据请求时常见到锁屏的loading动画,而现在越来越多的产品倾向于使用Skeleton Screen Loading(骨架屏)替代,以优化用户体验。
Skeleton Screen(骨架屏)就是在页面数据尚未加载前先给用户展示出页面的大致结构,直到请求数据返回后再渲染页面,补充进需要显示的数据内容。常用于文章列表、动态列表页。
我们都知道Ajax的请求,从客户端到服务端的数据请求之间有一段时间间隔,我们往往用一个loading图来提示用户数据正在加载来改善用户体验,就是我们经常用的菊花图:
loading图这种方式只能给提示用户,数据正在加载,但是这个时候页面往往是一片空白,视觉效果不是很好,在这里可以用另外一种方式来改善体验:Skeleton Screen,又称为骨架屏;即下面这种方式:
二、实现代码
完整例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Skeleton Screen</title>
<style type="text/css">
body {
background-color: #eaeef2;
}
.blog-container {
width: 1200px;
min-width: 1200px;
margin: 0 auto;
overflow: hidden;
}
.blog-wrap {
margin-top: 100px;
width: 860px;
}
.article {
position: relative;
width: 100%;
height: 214px;
padding: 20px 30px;
box-sizing: border-box;
background-color: #fff;
border-radius: 3px;
}
.article + .article {
margin-top: 10px;
}
.article-head {
width: 100%;
height: 25px;
line-height: 25px;
font-size: 20px;
margin-bottom: 15px;
cursor: pointer;
color: #00a67c;
}
.article-cover-box {
float: left;
margin-right: 20px;
width: 200px;
height: 123px;
}
.article-cover {
width: 100%;
height: 100%;
}
.article-content {
width: calc(100% - 220px);
height: 120px;
color: #888;
font-size: 14px;
line-height: 24px;
overflow: hidden;
}
.article-info {
position: absolute;
bottom: 0;
right: 30px;
min-width: 300px;
height: 20px;
line-height: 20px;
margin-bottom: 10px;
overflow: hidden;
text-align: right;
}
.article_info_item {
font-size: 13px;
color: #999;
}
.article_info_item + .article_info_item {
margin-left: 20px;
}
@keyframes placeHolderShimmer {
0% {
background-position: -860px 0
}
100% {
background-position: 860px 0
}
}
.animation-loading .animated-background {
animation-duration: 2s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: placeHolderShimmer;
animation-timing-function: linear;
background: #f6f7f8;
background: linear-gradient(to right, #eeeeee 8%, #dddddd 18%, #eeeeee 33%);
background-size: 860px 104px;
}
</style>
<script src="https://image.wxopen.club/content_87b7ab70-31c3-11ea-b391-38c9863fc7a9.png"></script>
</head>
<body>
<div id="main" class="blog-container">
<div class="blog-wrap">
<div class="article" :class="{'animation-loading': loading}" v-for="(article, index) in list" :key="index">
<div class="article-head animated-background">{{article.title || ''}}</div>
<div class="article-cover-box animated-background">
<img class="article-cover" v-if="article.bg" :src="article.bg">
</div>
<div class="article-content animated-background">{{article.content || ''}}</div>
<div class="article-info animated-background">
<span class="article_info_item">{{article.author || ''}}</span>
<span class="article_info_item">{{article.createdTime || ''}}</span>
<span class="article_info_item">{{article.viewNum || ''}}</span>
</div>
</div>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#main',
data: {
loading: false,
list: [{}, {}, {}, {}, {}]
},
created: function () {
var that = this;
that.loading = true;
setTimeout(function () {
that.list = [
{
title: 'Skeleton Screen最帅',
content: 'Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅',
bg: './images/img10.jpg',
createdTime: '2019/08/30 19:42:42',
author: 'GloryAce',
viewNum: '37浏览'
},
{
title: 'Skeleton Screen最帅',
content: 'Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅',
bg: './images/img12.jpg',
createdTime: '2019/08/30 19:42:42',
author: 'GloryAce',
viewNum: '37浏览'
},
{
title: 'Skeleton Screen最帅',
content: 'Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅',
bg: './images/img11.jpg',
createdTime: '2019/08/30 19:42:42',
author: 'GloryAce',
viewNum: '37浏览'
},
{
title: 'Skeleton Screen最帅',
content: 'Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅',
bg: './images/img13.jpg',
createdTime: '2019/08/30 19:42:42',
author: 'GloryAce',
viewNum: '37浏览'
},
{
title: 'Skeleton Screen最帅',
content: 'Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅,Skeleton Screen超级无敌帅',
bg: './images/img14.jpg',
createdTime: '2019/08/30 19:42:42',
author: 'GloryAce',
viewNum: '37浏览'
}
];
that.loading = false;
}, 5000);
}
})
</script>
</html>
三、总结
在网络环境比较差的情况下,使用Skeleton Screen可以显示一些视觉元素展现内容的轮廓,给用户比较友好的体验、一些等待预期。Skeleton Screen被越来越多的公司产品采用,如:支付宝,淘宝上都有很多的运用。
参考文章:
1、https://blog.csdn.net/i10630226/article/details/79590799
2、https://zhuanlan.zhihu.com/p/32941727