解决的场景是:当列表滚动停止并且停留了3s后,对可视区域内曝光超过80%的内容进行埋点上报。
方案一(有点笨重不细说,仅仅描述一下思路):
利用“截屏”的思想,先创建一个透明化view容器,然后设置定位,宽高设置100%,left偏移量100%, 当滚动截止后,让偏移量为0,再创建视口my.createIntersectionObserver,再通过视口的relativeTo去拿到所有相关的元素进行上报。 这个方案太笨重了,经过优化后改造成了第二个~~~~~
方案二:(本文的重点)
思路如下: 先监听页面是否滑动停止,滑动停止后开启3s定时器,若页面有滚动则停止计时。再一次滚动停止之后再重新计时。计时达到3s之后,开始视口监听,将会返回视口内的所有元素,之后处理上报。在上报函数里面可以处理去重,避免重复曝光。处理方式也比较简单,直接就存储所有的index/id,反正唯一标识就行了,上报之前判断一下是否存在,存在过滤掉即可~~~
下面提供关键的代码~~~收好了
1、监听滚动停止,然后销毁之前的定时器,重新开启定时器
// 监听页面滚动距离scrollTop
onPageScroll(e) {
this.cleanTimer(); //为了避免前一次的滚动停止后 停留时间不足三秒的题
let num = 0; //计数器
this.timer = setInterval(() => {
if (this.data.scrollTop === e.scrollTop) {
num++;
console.log(num);
if (num === 3) {
clearInterval(this.timer);
this.timer = null;
num = 0; //最好三秒过后 清零计数器 不然会出现定时器叠加的问题
this.setObverse(); //开始创建视口 获取相交元素进行上报
}
}
}, 1000);
},
2、清除定时器方法
cleanTimer() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
if (this.observe) {
this.observe.disconnect(); //这个是断开视口
}
},
3、触发视口,进行埋点上报
setObverse() {
this.initObverse();
const item_index = "item" //这里是元素class名,修改双引号内的值即可
this.observe.relativeToViewport({ top: 0, bottom: 0 }).observe(item_index, (res) => {
if (res.intersectionRatio > 0.8) { //这里是为了单个元素曝光超过80%,按需加入,不是必须的
this.handleMD(); //此处处理上报
}
});
},
4、创建视口
initObverse() {
//此处创建视口
this.observe = my.createIntersectionObserver({
selectAll: true, //是否同时观测多个目标节点(而非一个)
dataset: true, //目标节点的 dataset 信息。!!!要求小程序编译版本2.7.0以上!!!!不然h获取不到dataset信息!
thresholds: [0.8], //阈值。默认值为 [0]
});
},
5、处理埋点
handleMD() {
//此处处理埋点 ...
//小tips
//如果想进行排重曝光的话 最好在处理埋点之前 获取一下元素的唯一标识 类似id index等等,然后存起来 //上报之前 可以比对一下index的值 如果已经曝光过了 就不再进行上报
},
一点小总结,有更好的办法欢迎大佬们指导哟~~~~
第一次写文章,求轻喷~~~~~