adsense 上报广告的展示和点击行为
1.检测原生广告展示
js
const observedSet = new WeakSet();
const cbSet = new Set();
let timer = null;
async function handleAdStatus (adContainer) {
const adStatus = adContainer.getAttribute('data-ad-status');
let id = adContainer.querySelector('iframe')?.getAttribute('id');
if (adStatus === 'filled') {
if (cbSet.has(id)) return;
cbSet.add(id);
await trackEvent('ad_filled', { id });//打点
} else if (adStatus === 'unfilled') {
await trackEvent('ad_unfilled', { id });//打点
}
}
const io = new IntersectionObserver((entries) => {
entries.forEach(async entry => {
if (entry.isIntersecting) {
const adContainer = entry.target;
if (observedSet.has(adContainer)) return;
observedSet.add(adContainer);
const mo = new MutationObserver(async mutations => {
mutations.forEach(async mutation => {
if (mutation.type === 'attributes' && mutation.attributeName === 'data-ad-status') {
await handleAdStatus(adContainer);
if (adContainer.getAttribute('data-ad-status') === 'filled') {
mo.disconnect();
io.unobserve(adContainer);
}
}
});
});
mo.observe(adContainer, { attributes: true });
await handleAdStatus(adContainer);
if (adContainer.getAttribute('data-ad-status') === 'filled') {
mo.disconnect();
io.unobserve(adContainer);
}
}
});
}, {
threshold: 0.5 // 至少有 50% 可见才打点
});
timer = setInterval(() => {
const adContainers = document.querySelectorAll('.adsbygoogle');
adContainers.forEach(adContainer => {
io.observe(adContainer);
});
// 可选:如果所有广告都已处理,可以关闭定时器
if (cbSet.size === adContainers.length && timer) {
clearInterval(timer);
timer = null;
}
}, 1000);2.检测插屏广告的展示
js
let t = setInterval(async () => {
const hash = window.location.hash;
if (hash.indexOf('google') > -1) {
await trackEvent('ad_cp_filled'); //打点
clearInterval(t);
}
}, 1000);3.检测广告是否被点击了
js
// 在广告被填充的地方添加监听
bindAdEvents(dom)
function bindAdEvents (adSelectorDom) {
if (!adSelectorDom) {
return;
}
// PC端鼠标事件
adSelectorDom.addEventListener('mouseenter', () => { adHover = true; });
adSelectorDom.addEventListener('mouseleave', () => { adHover = false; });
adSelectorDom.addEventListener('mousedown', () => { adClicked = true; });
adSelectorDom.addEventListener('mouseup', () => { adClicked = false; })
// 移动端触摸事件
adSelectorDom.addEventListener('touchstart', () => { adTouch = true; }, { passive: true });
adSelectorDom.addEventListener('touchend', () => { adTouch = false; }, { passive: true });
adSelectorDom.addEventListener('touchcancel', () => { adTouch = false; }, { passive: true });
}
let adHover = false;
let adTouch = false;
let adClicked = false;
let lastVisibility = document.visibilityState;
onMounted(() => {
initAdClick()
})
const initAdClick = () => {
document.addEventListener('visibilitychange', async () => {
if ((adHover || adTouch) && document.visibilityState === 'hidden') {
// 打点、回传
}
if (document.visibilityState === 'visible') {
adHover = false;
adTouch = false;
adClicked = false;
}
lastVisibility = document.visibilityState;
});
window.addEventListener('blur', async () => {
if (adHover || adTouch) {
// 打点、回传
}
});
window.addEventListener('focus', () => {
adHover = false;
adTouch = false;
adClicked = false;
});
}以上代码只是会捕获到90%的点击,用户切换tab等其他一些操作可能也会被误认为点击,根据情况合理使用