微信小程序提供了一個很好用的api,IntersectionObserver 對象,監聽目標元素與其祖先或視窗交叉狀態的手段。
其實現原理在於監聽目標元素與參照區域相交(參照區域可以爲頁面顯示區域、指定一個元素節點);
這裏實現懶加載的原理就是如此,監聽需要加載的圖片,給圖片數組添加一個showState:false的字段,當使用IntersectionObserver 監聽到圖片進入參照區域時,動態改變showState爲true。
下面爲代碼:
wxml:
<view class="image-container">
<image wx:for="{{imageList}}" id="image_{{item.id}}" mode="widthFix" class="{{item.showState?'active':''}}" src="{{item.showState? item.src: ''}}" data-index="{{index}}"></image>
</view>
active爲一個opacity:0到opacity:1的動畫。
js部分:
//index.js
//獲取應用實例
const app = getApp()
Page({
data: {
imageList: [
{ id: 1, src: "../../images/label_bookcase_01.png",showState: false },
{ id: 2, src: "../../images/label_bookshelf_01.png", showState: false },
{ id: 3, src: "../../images/label_classification_01.png", showState: false },
{ id: 4, src: "../../images/label_home_01.png", showState: false },
{ id: 5, src: "../../images/label_my_01.png", showState: false },
{ id: 6, src: "../../images/no_cover.png", showState: false },
]
},
onLoad: function(){
this.setViewportListener();
},
setViewportListener: function(){
let that = this;
for(let i = 0;i<that.data.imageList.length;i++){
const viewPort = wx.createIntersectionObserver().relativeToViewport();
viewPort.observe(`#image_${i}`, (res) => {
//console.log("圖片進入視圖區域", res);
let index = res.dataset.index;
let keyStr = `imageList[${index}].showState`;
that.setData({
[keyStr]: true
})
viewPort.disconnect();
})
}
}
})