首先了解下什么是骨架屏?
骨架屏就是在頁(yè)面數(shù)據(jù)尚未加載前先給用戶展示出頁(yè)面的大致結(jié)構(gòu),直到請(qǐng)求數(shù)據(jù)返回后再渲染頁(yè)面,補(bǔ)充進(jìn)需要顯示的數(shù)據(jù)內(nèi)容。常用于文章列表、動(dòng)態(tài)列表頁(yè)等相對(duì)比較規(guī)則的列表頁(yè)面。 很多項(xiàng)目中都有應(yīng)用餓了么h5版本,知乎,facebook等網(wǎng)站中都有應(yīng)用。
以下圖舉例,常用餓了么的童鞋,應(yīng)該看到過(guò)餓了么的這個(gè)首頁(yè)預(yù)加載圖的效果:
餓了么h5實(shí)現(xiàn)方案

咱們來(lái)聊聊小程序的實(shí)現(xiàn)方案:
1.最簡(jiǎn)單最快捷的最暴力的,直接讓設(shè)計(jì)一張圖片蓋上去,當(dāng)loading使用。
舉例:餓了么的訂單頁(yè)面,查看了下源碼,是使用的SVG的圖

2.前端使用view寫死一套數(shù)據(jù)(缺點(diǎn)很明顯,假如頁(yè)面布局有修改的話,那么除了修改業(yè)務(wù)代碼之外還需要額外修改骨架屏,增加了維護(hù)的成本)
舉例:簡(jiǎn)單寫了個(gè)代碼片段:https://developers.weixin.qq.com/s/ZAuYzHmX7ObC

3.頁(yè)面Data里寫死一套默認(rèn)數(shù)據(jù),使用小程序的wx.createSelectorQuery().selectAll 選擇了所有要渲染的矩形和圓形節(jié)點(diǎn),在頁(yè)面中,使用循環(huán),遍歷出所有的節(jié)點(diǎn),再加上樣式。
基本原理就是
-
在組建初始化時(shí),設(shè)置其絕對(duì)定位,大小為整個(gè)屏幕大小
-
然后用節(jié)點(diǎn)查詢方法,找到類名等于skeleton的元素,并設(shè)置組件的背景的位置及大小和元素的一致,覆蓋這個(gè)元素。
-
用節(jié)點(diǎn)查詢方法,找到所有的類名等于skeleton-radius 元素,并將它們的位置及大小信息加入到sklection-radius-Arr數(shù)組中,在wxml中用wx:for循環(huán)渲染出來(lái)(也是絕對(duì)定位)
-
用節(jié)點(diǎn)查詢方法,找到所有的類名等于skeleton-rect 元素,并將它們的位置及大小信息加入到sklection-rect-Arr數(shù)組中,在wxml中用wx:for循環(huán)渲染出來(lái)(也是絕對(duì)定位)
當(dāng)然啦,這里還有一些判斷,還可以設(shè)置屏幕上提示是旋轉(zhuǎn)小圈圈還是背景色漸變提醒等,都是一些比較細(xì)節(jié)的東西,就不細(xì)說(shuō)。
具體代碼參考:jayZOU,這里有他具體源碼以及實(shí)現(xiàn)邏輯,使用后會(huì)發(fā)現(xiàn)有些許異常未處理。
那么到這就完了嗎?當(dāng)然木有,現(xiàn)在說(shuō)下最后一種方案(目前我們小程序正在使用的方案)。
4. 如何更好的把骨架屏代碼嵌入到業(yè)務(wù)里面,是否可以在接口請(qǐng)求成功后,先渲染出一套接口返回的數(shù)據(jù)匹配的骨架,再展示給用戶看呢,減少用戶查看白屏(loading)時(shí)間。
這是我們線上版本效果示例圖:

首先來(lái)看 如何操作:
整個(gè)前邊部分跟jayZOU的邏輯思路一樣,使用wx.createSelectorQuery 獲取到相關(guān)節(jié)點(diǎn)進(jìn)行渲染操作,但是我們把默認(rèn)數(shù)據(jù)這一欄更改為動(dòng)態(tài)數(shù)據(jù),并且兼容修復(fù)了一部分bug。
核心代碼就是自定義組件內(nèi)拋出的isNodes和isComplete屬性
//wxml
<skeletons isNodes="{{isNodes}}" isComplete="{{isComplete}}"" />
//頁(yè)面節(jié)點(diǎn)上需要手動(dòng)添加一個(gè)樣式類。
比如輪播圖 寬686rpx,高140rox,是長(zhǎng)方形那么給他的樣式上加上‘skeletions-rect’,如果是圓形給他加上‘skeletons-circle’
業(yè)務(wù)內(nèi)代碼如下:
<!-- 輪播圖組件 -->
<block wx:if="{{swiperData.length > 0}}">
<swiper class="swiperSlide" indicator-dots="{{indicatorDots}}" indicator-color="#ccc" indicator-active-color="#00CC88" autoplay circular>
<block wx:for="{{swiperData}}" wx:key="{{index}}">
<swiper-item>
<view class="swiper-item">
<image lazy-load src="{{item.image}}" data-index="{{index}}" bindtap="universalJump" class="skeletons-rect" />
</view>
</swiper-item>
</block>
</swiper>
<!-- <qts-swiper resourseFrom="{{swiperData}}" indicatorDots="{{indicatorDots}}"></qts-swiper> -->
</block>
相關(guān)JS如下:
initData() {
let postData = {
townId: wx.getStorageSync('townId') || 87
}
// 初始化請(qǐng)求第一個(gè)接口
app.postAjax('https://url.com', postData).then((res) => {
if (res.success) {
this.setData({
bodyData: res.data, //頁(yè)面展示數(shù)據(jù)的大對(duì)象
isNodes: true //抓取節(jié)點(diǎn)繪制骨架屏
}, () => {
this.setData({
isComplete: true //節(jié)點(diǎn)繪制完成,隱藏骨架屏
})
})
} else {
util.toast(res.msg || '團(tuán)團(tuán)開小差啦,請(qǐng)稍后重試')
}
}, () => {
util.toast('團(tuán)團(tuán)開小差啦,請(qǐng)稍后重試')
})
},
目前遇到的難點(diǎn)在于,把功能點(diǎn)抽成自定義組件。skeletons的class類無(wú)法傳遞進(jìn)去,試過(guò)用外部樣式影響自定義組件樣式,還是無(wú)法達(dá)到效果。如果有解決這個(gè)問(wèn)題的歡迎留言溝通優(yōu)化~
最后完整組件代碼地址:https://gitee.com/minchangyong/skeletons
已新增支付寶版本
社區(qū)關(guān)注可以走一走哦~:
微信點(diǎn)我去關(guān)注
支付寶點(diǎn)我去關(guān)注
青團(tuán)社招聘:
招聘崗位:資深前端開發(fā)工程師P6及以上
坐標(biāo)杭州市余杭區(qū)文一西路1380號(hào)金之源大廈11層
簡(jiǎn)歷投遞到:hr@qtshe.com
職位描述:
1、負(fù)責(zé)前端模塊(PC、移動(dòng)、小程序)的重要方案設(shè)計(jì)與研發(fā)
2、研究和探索創(chuàng)新的開發(fā)思路和前端技術(shù),優(yōu)化前端框架、設(shè)計(jì)方案,提高前端的開發(fā)交付效率。
3、理解產(chǎn)品業(yè)務(wù)的基礎(chǔ)上,提升產(chǎn)品用戶體驗(yàn),技術(shù)驅(qū)動(dòng)業(yè)務(wù)發(fā)展。
4、定期組織主題分享,活躍技術(shù)氛圍,帶動(dòng)組員提升技術(shù)能力
任職資格與條件要求描述
1、對(duì) MVC/MVMM 有一定的理解,至少熟練掌握一個(gè)或多個(gè)前端框架(React、Vue等)
2、代碼結(jié)構(gòu)清晰,javascript基礎(chǔ)扎實(shí),精通任意一門前端MV*框架,如Vue、React等
3、熟悉 HTTP 協(xié)議,熟悉 Web 應(yīng)用的性能優(yōu)化,監(jiān)控,分析方法
4、溝通能力強(qiáng),責(zé)任心強(qiáng),思維邏輯性強(qiáng)