前言
在微信小程序中,实现图片懒加载的方式有很多
实现思路
image标签里的lazy-load属性- 通过监听滚动条滑动事件,判断元素距离页面顶部的距离是否小于等于页面的可视高度
Intersection Observer API
鉴于第一种方式目前看不出效果,第二种方式代码量还是有点大的,我们在这里用第三种方式来实现图片懒加载。
官方解释
WXML节点布局相交状态
- 节点布局交叉状态API可用于监听两个或多个组件节点在布局位置上的相交状态。这一组API常常可以用于推断某些节点是否可以被用户看见、有多大比例可以被用户看见。
- 涉及到以下几个概念
-
参照节点:监听的参照节点,取它的布局区域作为参照区域。如果有多个参照节点,则会取它们布局区域的 交集 作为参照区域。页面显示区域也可作为参照区域之一。
-
目标节点:监听的目标,默认只能是一个节点(使用 selectAll 选项时,可以同时监听多个节点)。
-
相交区域:目标节点的布局区域与参照区域的相交区域。
-
相交比例:相交区域占参照区域的比例。
-
阈值:相交比例如果达到阈值,则会触发监听器的回调函数。阈值可以有多个。
-
代码实现
1. wxml文件
<scroll-view>
<view class="image-panel item item-{{index}}" wx:for="{{list}}" wx:for-item="item" wx:key="{{index}}">
<view class="video-play" bindtap="linkToDetail">
<image class="{{item.show ? 'active': ''}}" src="{{item.show ? item.cover : default}}" mode="widthFix" lazy-load />
</view>
</view>
</scroll-view>
注意
- 这里用到了第一种方式,也就是在
image标签里加上了lazy-load属性,要配合scroll-view使用才有效果。可惜,在本地没有测出效果。 - 通过
show这个字段来判断是否显示原图,未加载的情况下使用默认图来展示。
2. js文件
const url = "";//业务api地址
const that = this;
const obj = {
method: 'get',
url: url,
success: function (res) {
var items = res.data.items;
that.setData({
list: items
})
setTimeout(() => {
for (let i in res.data.items) {
wx.createIntersectionObserver().relativeToViewport({bottom: 20}).observe('.item-' + i, (res) => {
if (res.intersectionRatio > 0) {
items[i].show = true
}
that.setData({
list: items
})
})
}
}, 1*1000);
}
}
common.httpRequest(obj)
注意
- 监听的节点需要先渲染,所以需要初始化列表,并用默认图占位。
- 延迟执行
createIntersectionObserver()方法
总结
- 初始化列表是否可以初始化部分图片,或者首屏图片。
- 监听需要依赖节点的className,需要等前一个节点循环完成,才能监听下一个,目前是用延迟来处理的,可能还有更好的方案?