利用移动端击穿的原理进行百度广告点击统计,实施很简单,在百度广告上方放置一透明层,当用户点击时发送统计日志,
移动端击穿的原因,网上文章很多,大意是click事件会有相对于touch事件300毫秒的延迟触发(因需要判断双击还是单击),
可以利用这一点当touch事件触发时隐藏浮层,click 事件应用时刚好点到广告;比如使用工具的tap事件,当然自己写原生也很简单,
监听touchend事件,监听touchstart 事件,对比两次事件的时间戳及触摸点的位移情况就可以判定用户是点击了还是划屏、长按操作。
具体的原理是利用移动端的点击事件击穿现象:点击判断延迟(因为要判断是否是双击,所以在点击后300毫秒的时间内来检测有没有再次点击来判定是否是双击);
要监听百度广告的点击需要在广告的上方生成一个透明的层,给这个层加上一个touch事件(具体实现可以自由发挥),需要在touchend 的时候来隐藏透明层,上报统计数据,只有touchend 是不行的,还要通过额外的touchstart 来判断 是不是用户的点击操作(具体检测有比如通过划过的距离来判断不是划屏是点击还有就是长按操作),有点像,tap 事件。
一个点击事件的触发流是这样的 touchstart -----> touchmove ------> touchend ------->click
从touchstart --------> click作用于元素, 其间有300毫秒的间隔,在此其间搞一些事情还是有余地的
有道是理想很丰满现实很骨感,说一下遇到的问题,
【问题一】百度失效广告
百度给出的对象BAIDU_DUP.slot.slotsMap提供了广告的长宽高等信息,实际有些广告可能在页面的宽度高度是0,
【解决方案】可以把广告去了,也可以无视
【问题二】
iphone 6plus safari 点击后层消失,但广告没有得到点击,在需要击穿的时候竟然不击穿,真是一个讽刺。。。
问题很严重,经过更详细的测试发现,快速的点击,只是层消失,广告不被点击,但是点慢一些的时候,还是会成功跳转,
这个问题就比较有意思了,要求用户点慢一些显然是不现实的,
【解决方案】
瞎猫碰上死耗子,在解决别的问题时,这个问题被意外的解决了。。。,
神器 【setTimeout】
仅仅使用setTimeout 异步生成浮层元素 结果好了,虽然这个解释很不负责任,你问我我也不知道,这个就像切图各种兼容,一个float解决一样;
【注意事项】
不建义 这样写法,setTimeout("alert(1)",2000);因为字符串需要解析性能不好,这样写多好setTimeout(function(){alert(1)},2000)
【贴代码】
;(function ($, doc, win, undefined) {
var fn = function () {
};
fn.prototype = {
cache: {},
init: function () {
var _this = this;
this.bindEvent();
setTimeout(function () {
_this.createMask();
}, 0);
/*setTimeout(function(){ _this.checkAd(); },7000)*/
},
bindEvent: function () {
var xS, yS, xE, yE, tS, tE;
doc.addEventListener("touchstart", function (evt) {
if (evt.target.className != "BDHCX161229") return;
var temp = evt.touches[0];
xS = temp.clientX;
yS = temp.clientY;
tS = evt.timeStamp;
}, false);
doc.addEventListener("touchend", function (evt) {
if (evt.target.className != "BDHCX161229") return;
var temp = evt.changedTouches[0] || evt.touches[0];
xE = temp.clientX;
yE = temp.clientY;
tE = evt.timeStamp;
//console.log(tE-tS,":",xE-xS,":",yE-yS);
if (tE - tS < 300 && !(xE - xS) && !(yE - yS)) {
$(evt.target).hide();
sendUserlogsElement("UserBehavior_adbaidu_" + evt.target.getAttribute("data-id"));
}
//多标签兼容处理
setTimeout(function () {
$(evt.target).show()
}, 1000)
}, false);
//修正 iphone safari 后退
doc.addEventListener("pageshow", function (evt) {
evt.persisted && $(".BDHCX161229").show();
}, false);
},
createMask: function () {
var data = win.BAIDU_DUP && win.BAIDU_DUP.slot && win.BAIDU_DUP.slot.slotsMap ? win.BAIDU_DUP.slot.slotsMap : {};
var temp;
var top, left;
var tempEle;
for (var i in data) {
if (!data.hasOwnProperty(i)) continue;
temp = data[i];
tempEle = doc.createElement("div");
tempEle = $('<div class="BDHCX161229"></div>');
tempEle[0].setAttribute("data-id", temp.slotId);
tempEle[0].style.cssText = "opacity:0;background-color:#000;cursor:pointer;position:absolute;z-index:1;left:0px;top:0px;width:" + temp.width + "px;height:" + temp.height + "px";
(function (id, ele) {
setTimeout(function () {
$("#" + id).css("position", "relative").append(ele);
id = null;
ele = null;
}, 0);
})(temp.containerId, tempEle)
}
}
};
$(function () {
new fn().init();
});
})(window.jQuery || window.Zepto, document, window);