第一步创建曝光对象
//创建曝光对象
this._observer = uni.createIntersectionObserver(this, {
//thresholds: [0],
observeAll: true
});
因为我项目是用uniapp写的,所以用的uni,微信的话直接wx就行,api使用方式是一样的
详细的api可以直接看文档,这里只说一下我用到的一些api和参数
thresholds:官方解释是阈值。这里可以通俗的理解为需要监听的对象刚进入选定对象与完全进入选定对象。或者在这里可以理解为上拉滑动时图片的上边界触碰到可视区域的下边界此时的情况thresholds就是0,继续向上,当图片的下边界触碰到可视区域的下边界,此时thresholds为1(因为我是打算图片刚进去选定的对象时进行回调,所以不填,默认为0)
observeAll: true为选定所有节点,默认为false,我们这边图片肯定是要选择全部的
第二步设置选定节点与监听节点
//rescv是返回的列表接口的数据
//这里是给它添加是否需要加载的状态lazyLoad
//src是图片默认图片,可以前台自己加也可以后台接口加上后给前台
rescv.forEach((item)=>{
item.lazyLoad = true;
item.src = '/static/noData.png';
})
//判断this._observer是否存在,存在则销毁
//确保每次只有一个this._observer
if (this._observer) {
this._observer.disconnect();
}
//监听视图窗口与图片相交的回调
//写在$nextTick里面,确保监听对象已经渲染出来
this.$nextTick(() => {
this._observer.relativeToViewport({
//bottom表示 .image_lazy元素 距离窗口1000px时调用函数
bottom: 1000
}).observe('.image_lazy', (res) => {
//如果lazyload为true表示还未加载过图片,此时加载图片,同时lazyload设为false
if (res.dataset.lazyload) {
let copyDetail =
JSON.parse(JSON.stringify(this.detail[res.dataset.index]));
copyDetail.src = res.dataset.src;
copyDetail.lazyLoad = false;
//这里写法是因为用的是uniapp,vue的写法,所以如果直接给数组索引赋值无法刷新
//视图
//以下写法可以强制刷新
//原生小程序写法的话不需要
this.$set(this.detail, res.dataset.index, copyDetail);
}
})
})
部分html代码
//这里是用到的图片html
<image :data-src="item.imgs[0].url" :data-lazyLoad="item.lazyLoad" :data-index="index"
class="image_lazy" mode="aspectFill" :src="item.src" />
使用注意:1.必须用在获取列表数据并且渲染之后,否则会导致获取不到监听对象
2.因为正常情况来说,后台返回列表都会进行分页,每次请求都会创建一个的 observer,所以必须在每次创建前销毁上一个
observer
以上对于intersectionObserver的理解仅为个人观点,如有错误请见谅