背景
写业务代码的时候,可能经常遇到滚动,然后,具体曝光某个模块的情况
下面是封装的函数,还有具体的使用
code
import { jsBridge } from 'xxx-xx';
export default {
data () {
return {
viewHeight: null,
scrollEventFun: null
}
},
mounted () {
// 页面渲染完成,执行曝光检测
setTimeout(() => {
this.viewHeight = window.innerHeight;
this.scrollEvent();
// 监听scroll事件
this.scrollEventFun = this.throttle(this.scrollEvent, 300);
window.addEventListener('scroll', this.scrollEventFun, false);
}, 1000);
},
beforeDestroy () {
// 防止内存溢出
window.removeEventListener('scroll', this.scrollEventFun, false);
},
methods: {
getOffsetTop (element) {
let actualTop = element.offsetTop;
let current = element.offsetParent;
while (current !== null) {
actualTop += current.offsetTop;
current = current.offsetParent;
}
return actualTop;
},
// time 必然触发执行的时间间隔
throttle (fun, threshhold = 160) {
let timeout;
let startTime = new Date();
return function () {
let context = this;
let args = arguments;
let curTime = new Date() - 0;
clearTimeout(timeout);
if (curTime - startTime >= threshhold) {
fun.apply(context, args);
startTime = curTime;
} else {
timeout = setTimeout(function () {
fun.apply(context, args);
}, threshhold);
}
};
},
// 获取窗口滚动高度
scrollTop () {
return document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset;
},
scrollEvent () {
let $scrollTop = this.scrollTop();
let nodeArr = document.querySelectorAll('.has-exp');
for (let i = 0; i < nodeArr.length; i++) {
let domTop = this.getOffsetTop(nodeArr[i]) + nodeArr[i].getBoundingClientRect().height / 3;
// 当正文部分露出即发此曝光
if (nodeArr[i].getAttribute('detail-article') === '1') {
domTop = this.getOffsetTop(nodeArr[i]);
}
let topHeight = this.getOffsetTop(nodeArr[i]) - $scrollTop;
// console.log('topHeight', topHeight);
let bottomHeight = domTop - $scrollTop;
if (topHeight >= 0 && bottomHeight <= this.viewHeight) {
if (!nodeArr[i].getAttribute('data-exposure')) {
nodeArr[i].setAttribute('data-exposure', '1');
const _this = this;
new Promise((resolve) => {
resolve();
}).then(() => {
let expData = nodeArr[i].getAttribute('exp-data');
_this.expPost(expData);
});
}
}
if (topHeight > this.viewHeight) return false;
}
},
expPost (mapData) {
if (mapData) {
mapData = JSON.parse(mapData);
}
const message = {
action: 'exposure',
map: mapData
};
console.log(`曝光统计log: ${JSON.stringify(message)}`);
jsBridge(message);
}
}
};
<div class="has-exp" exp-data="{'key': 'val'}">
我是要曝光的模块
</div>