骨架屏
在小程序中,页面层与逻辑层通信,还有服务器端通信需要一定的时间,这为用户的体验带来不小的挑战。
为了减少用户等待的焦虑,以及减少用户离开页面的时间。所以让用户提前感知此页面在运行,和用户提前聚焦内容,于是使用骨架屏作为初次渲染。
绘制骨架
骨架元素分为两种:
- 圆形
- 长方形
长方形的绘制:
<div class="rect"></div>
<style>
.rect {
height: 20rpx;
width: 100vw;
background-color: #dcdde1;
}
</style>
圆形只需要在正方形的基础上加上border-radius:100%即可,例子如下:
<div class="cir"></div>
<style>
.cir {
height: 50rpx;
width: 50rpx;
background-color: #dcdde1;
border-radius: 100%;
}
</style>
绘制的骨架
在小程序中,提供selectAll这个API可以帮我选择出页面中的元素。
选择整个页面中的.rect元素,我们将其包装成异步的模式:
async function selectAll(selector) {
return new Promise((resolve, reject) => {
uni
.createSelectorQuery()
.selectAll(selector)
.boundingClientRect()
.exec(res => resolve(res));
});
}
然后就可以使用selectAll函数选择页面中的元素。
定位元素
页面中的元素定位有多种,但是骨架屏因为它不会运动,不会左右摇晃,更不会变色。
所以在页面中使用绝对定位,可以精确找到落在页面上的元素。
<div class="skeleton-contain">
<div class="rect"></div>
</div>
<style>
.skeleton-contain {
height: 100vw;
width: 100vw;
position: absolute;
}
.rect {
top: 20rpx;
height: 20rpx;
width: 100vw;
background-color: #dcdde1;
}
</style>
由于前面的selectAll函数,那么它返回的字段形如:
{
"bottom": 262,
"dataset": Object,
"height": 60,
"id": "",
"left": 37.5,
"right": 97.5,
"top": 202,
"width": 60
}
这时,我们就可以找到它的定位点在哪里,并以循环节点的方式绘制:
<template>
<view class="skeleton-contain">
<view
v-for="(item, index) in rectList"
:key="index"
class="rect"
:style="[
{
height: `${item.height}px`,
width: `${item.width}px`
},
{
top: `${item.top}px`,
bottom: `${item.bottom}px`,
right: `${item.right}px`,
left: `${item.left}px`
}
]"
></view>
</view>
</template>
<script>
export default {
name: 'skeleton',
mounted() {
this.drawRect();
},
data() {
return {
rectList: []
};
},
methods: {
async selectAll(selector) {
return new Promise((resolve, reject) => {
uni
.createSelectorQuery()
.selectAll(selector)
.boundingClientRect()
.exec(res => resolve(res));
});
},
async drawRect() {
const [rect] = await this.selectAll('.rect');
this.rectList = rect;
}
}
};
</script>
<style>
.skeleton-contain {
height: 100vw;
width: 100vw;
position: absolute;
}
.rect {
background-color: #dcdde1;
}
</style>
这样,一个完整的骨架也就做出来了。