公司需求,需要监听谷歌点击统计!
想了几种方案:
方案一 事件委托(不可取)、
给iframe里面监听方法,通过contentWindow 去执行事件委托;
这种方案,不可取~因为同源策略,iframe下面引入了谷歌的第三方的URL,出现了跨域问题;
除非你可以在广告生成页里面下个调用方法,来调取你当前页写的方法;
var ifr = document.querySelectorAll('iframe');
ifr.forEach(item =>{
let ctw = item.contentWindow;
ctw.addEventListener('click',function(e){
console.log(e.srcElement)
})
})
那给包裹广告的ins标签或者div标签,监听事件?
好像还是不行,iframe框架在当前页面展示层,
方案二 事件穿透(不可取)、
在外层谷歌广告外层添加一个遮罩,那么用户点击行为的时候,可以实现用户行为采集,也是很棒的想法;
在广告容器下面,做个div遮罩,<div class="mask" style="position:absolute;top:0px;right:0px;width:100%;height:100%;z-index:99;"></div>;
(1)、然后根据事件 mousedown -> mousemove -> mouseup -> click / touchstart -> touchmove -> touchend -> tap 的优先顺序
(2)、或者用css3的 pointer-events:none用在mask上面
(3)、在遮罩下面绑定事件,从而触发,这又回到第一个问题,跨域问题,谷歌广告是不可能让你写方法的,那么这个方案又不行
方案三 轮训与事件监听(可取)
上面方案不行,总得找出一个出路解决监听的方案~
不能动谷歌的ins\iframe的document,那么就去监听当前页,总可以吧~
这里用到了h5新增方法activeElement,这个是用来监听当前执行元素
然后通过一个轮询方法,监听这个document.activeElement对象,做iframe匹配;
终于可以监听到iframe这也是个进步,那么点击谷歌广告时,至少可以给你个响应,并且不报错了
var IframeOnClick = {
istrack:null,
resolution: 200,
iframes: [],
interval: null,
Iframe: function() {
this.element = arguments[0];
this.cb = arguments[1];
this.hasTracked = false;
},
track: function(element, cb) {
this.iframes.push(new this.Iframe(element, cb));
if (!this.interval) {
var _this = this;
this.interval = setInterval(function() {
_this.checkClick();
}, this.resolution);
}
},
checkClick: function() {
if (document.activeElement) {
var activeElement = document.activeElement;
var tagName = activeElement.tagName;
for (var i in this.iframes) {
if (activeElement === this.iframes[i].element) {
if (this.iframes[i].hasTracked == false) {
this.iframes[i].cb.apply(window, []);
this.iframes[i].hasTracked = true; }
}
}
}
}
};
window.onload = function(){
var ifs = document.getElementsByClassName("iframe");
for (var i = 0; i < 12; i++) {
IframeOnClick.track(ifs[i], function() {
console.log("click");
// 这里写一些业务逻辑,例如给变量添加状态
IframeOnClick.istrack = true;
});
}
}
接着讲,只点击谷歌广告,还达不到监控是否点击a标签跳转啊,要是点击的空白处,也是返回的iframe对象,不是很尴尬;这个时候只能通过其他的方法,去到达a跳转的效果;
配合方法h5新增方法,document.hidden 与 visibilityChangeEvent这个事件配合用,能监听当前页面是否是激活状态,a标签既然会跳转页面,那么当前页面肯定就是非激活状态;这时候配合上面方法;
(1)找到IframeOnClick下面的istrack,它是用来标记状态的
(2)当点击谷歌广告并跳转时,那么给这个IframeOnClick.istrack = true;
(3)在页面非激活状态下,通过判断istrack这个变量,实现业务逻辑,例如ajax 当前的location值啊,获或者获取当前用户IP,这些都是没问题的;
(4)在页面激活状态,你得把istrack这个变量还原为 null, istrack = null;
排除点击广告没跳转,又点击了你们自己的页面链接出现错误数据统计
// 判断是否在当前页面
var hiddenProperty = 'hidden' in document ? 'hidden' : 'webkitHidden' in document ? 'webkitHidden' : 'mozHidden' in document ? 'mozHidden' : null;
var visibilityChangeEvent = hiddenProperty.replace(/hidden/i, 'visibilitychange');
var onVisibilityChange = function(){
if (!document[hiddenProperty]) {
console.log('页面非激活');
if(IframeOnClick.istrack){
//执行你要的逻辑
}
}else{
console.log('页面激活')
IframeOnClick.istrack = null;
}
}
document.addEventListener(visibilityChangeEvent, onVisibilityChange);
感谢大神们的分享,这里做个mark,方便以后自己看,如果有用,点个👍