场景:滚动翻页的列表中的数据滚动到可视区域内立即曝光埋点
实现思路:给需要曝光的元素添加指定属性,监听滚动停止时获取含有该指定属性的元素,如果在可视区域内就上报,已上报过的不再重复上报
详细实现过程见代码
1、列表中的元素添加指定属性,属性值为上报埋点搜索需要的参数
<li class="templist-item" v-for="(item, index) in datalist" :key="index"
:data-exposure="`{
eventName: 'order_exposure',
nsid: '${item.nsid}',
productId:'${item.id}',
sdata: '${item.sdata||''}',
commonName: '${item.showName}',
position: '${index}',
}`"
>
某某列表项
</li>
2、曝光埋点实现方法
// 漏出曝光埋点
exposureView(){
let eles = document.querySelectorAll("[data-exposure]");
eles = [...eles];
eles.forEach((item) => {
const attrs = item.getAttribute('data-exposure');
if (attrs) {
// hasTrack-是否已上报
const hasTrack = item.getAttribute('hasTrack');
if (this.isElementInViewport(item)) {
// 在可见区域内没有上报的才会上报
if (hasTrack === 'false' || !hasTrack) {
const child = eval("("+attrs+")");
if (child.eventName == 'order_exposure') {
// 这里是调用的封装的埋点方法,各位看自己项目如何上报
actionTracking(child.eventName, {
nsid: child.nsid,
productId: child.productId,
sdata: child.sdata || '',
position: child.position || null,
cate_position: child.cate_position || -1,
cate_text: child.cate_text || '',
})
}
item.setAttribute('hasTrack', true);
// item.removeAttribute('data-exposure');
}
} else {
item.setAttribute('hasTrack', false);
}
}
})
},
// 判断是否在可视区域内
isElementInViewport(el) {
var rect = el.getBoundingClientRect();
var width_st = rect.width,
height_st = rect.height;
var innerHeight = window.innerHeight,
innerWidth = window.innerWidth;
if ( rect.top <=0 && rect.height > innerHeight
|| rect.left <= 0 && rect.width > innerWidth
) {
return rect.left * rect.right <= 0
|| rect.top * rect.bottom <= 0
}
return (
rect.height > 0
&& rect.width > 0
&& ( ( rect.top >= 0 && rect.top <= innerHeight - height_st )
|| ( rect.bottom >= height_st && rect.bottom <= innerHeight ) )
&& ( ( rect.left >= 0 && rect.left <= innerWidth - width_st )
|| ( rect.right >= width_st && rect.right <= innerWidth ) )
);
},
3、在页面监听滚动的地方调用exposureView方法即可,注意:因为是滚动时调用,会导致首屏没有默认上报,在mounted生命周期中调用一下就可以。