骨架屏
在小程式中,頁面層與邏輯層通訊,還有伺服器端通訊需要一定的時間,這為使用者的體驗帶來不小的挑戰。
為了減少使用者等待的焦慮,以及減少使用者離開頁面的時間。所以讓使用者提前感知此頁面在執行,和使用者提前聚焦內容,於是使用骨架屏作為初次渲染。
繪製骨架
骨架元素分為兩種:
- 圓形
- 長方形
長方形的繪製:
<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>
複製程式碼
這樣,一個完整的骨架也就做出來了。