实现延迟加载的方法
1:通过监听滚动条滑动事件,判断元素距离页面顶部的距离是否小于等于页面的可视高度
Page({
data: {
realScrollTop: 0,//页面滚动距离
driveHeight //屏幕高度可初始化设置
},
scroll(e){
if(e.detail.scrollTop > this.data.realScrollTop){
this.setData({
realScrollTop: e.detail.scrollTop
});
}
}
});
<scroll-view scroll-y="true" scroll-top="{{resetScrollTop}}" bindscroll="scroll" >
<image wx:if="{{realScrollTop+driveHeight*2 > (index*70)}}" src="{{item['img']}}"></image>
<image wx:else src="{{item['bgm']}}"></image>
</scroll-view>
2:Intersection Observer API(官方案例)
WXML
节点布局相交状态
- 节点布局交叉状态API可用于监听两个或多个组件节点在布局位置上的相交状态。这一组API常常可以用于推断某些节点是否可以被用户看见、有多大比例可以被用户看见。
- 涉及到以下几个概念
- 参照节点:监听的参照节点,取它的布局区域作为参照区域。如果有多个参照节点,则会取它们布局区域的 交集 作为参照区域。页面显示区域也可作为参照区域之一。
- 目标节点:监听的目标,默认只能是一个节点(使用 selectAll 选项时,可以同时监听多个节点)。
- 相交区域:目标节点的布局区域与参照区域的相交区域。
- 相交比例:相交区域占参照区域的比例。
- 阈值:相交比例如果达到阈值,则会触发监听器的回调函数。阈值可以有多个。
<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>
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)
3:image
标签里的lazy-load
属性
最近在开发家里喵喵的小程序(娱乐),本想抽一小部分时间做个懒加载。看了小程序官网 API,给 image 标签加上 lazy-load 就能实现懒加载。但从微信开发者工具看,似乎并没有生效。搜了一下,很多小伙伴似乎都遇到了问题,并没有解决。
但经过我的验证, 懒加载确实是生效了 。
只不过, 小程序会提前加载当前屏幕和下一屏的图片,导致感知不到懒加载的存在。
个人认为,这样的懒加载比传统懒加载的体验更加好。
我的验证过程:
wxml部分(用 scroll-view 并且加上 bindload):
<scroll-view class="container" scroll-y>
<view wx:for="{{list}}" class="list-item">
<image class="list-img" lazy-load src="{{item.img}}" bindload='onLazyLoad'></image>
<view>{{item.desc}}</view>
</view>
</scroll-view>
js部分:
const app = getApp()
Page({
data: {
list: []
},
onLazyLoad(info) {
console.log(info)
}
})
4:
定义
懒加载,前端人都知道的一种性能优化方式,简单的来说,只有当图片出现在浏览器的可视区域内时,才设置图片正真的路径,让图片显示出来。这就是图片懒加载。
实现原理
监听页面的scroll
事件,判读元素距离页面的top
值是否是小于等于页面的可视高度
判断逻辑代码如下
element.getBoundingClientRect().top <= document.documentElement.clientHeight ? 显示 : 默认
我们知道小程序页面的脚本逻辑是在JsCore中运行,JsCore是一个没有窗口对象的环境,所以不能在脚本中使用window,也无法在脚本中操作组件。
所以关于图片懒加载就需要在数据上面做文章了。
页面
页面上面只需要根据数据的某一个字段来判断是否显示图片就可以了,字段为Boolean类型,当为false的时候显示默认图片就行了。
代码大概长成这样
<view wx:for="{{list}}" class='item item-{{index}}'
wx:key="{{index}}">
<image class="{{item.show ? 'active': ''}}" src="{{item.show ? item.src : item.def}}"></image>
</view>
布局跟简单,view
组件里面有个图片,并循环list
,有多少就展示多少
image
组件的src
字段通过每一项的show
来进行绑定,active
是加了个透明的过渡
样式
image{
transition: all .3s ease;
opacity: 0;
}
.active{
opacity: 1;
}
逻辑
本位主要讲解懒加载,所以把数据写死在页面上了
数据结构如下:
我们使用两种方式来实现懒加载,准备好没有,一起来快乐的撸码吧。
WXML节点信息
小程序支持调用createSelectQuery创建一个SelectorQuery
实例,并使用select
方法来选择节点,并通过boundingClientRect
来获取节点信息。
wx.createSelectorQuery().select('.item').boundingClientRect((ret)=>{
console.log(ret)
}).exec()
显示结果如下
悄悄告诉你,小程序里面有个onPageScroll
函数,是用来监听页面的滚动的。
还有个getSystemInfo
函数,可以获取获取系统信息,里面包含屏幕的高度。
接下来,思路就透彻了吧。还是上面的逻辑, 扒拉扒拉直接写代码就行了,这里只写下主要的逻辑,完整代码请戳文末github
showImg(){
let group = this.data.group
let height = this.data.height // 页面的可视高度
wx.createSelectorQuery().selectAll('.item').boundingClientRect((ret) => {
ret.forEach((item, index) => {
if (item.top <= height) { 判断是否在显示范围内
group[index].show = true // 根据下标改变状态
}
})
this.setData({
group
})
}).exec()
}
onPageScroll(){ // 滚动事件 this.showImg()
}