对于我们网站上的一堆锚标签,我们发送一个事件到谷歌分析,以跟踪用户的行为,现在我使用以下代码(点击触发):
event.preventDefault();
ga(tracker, 'event', category, action, label, value, { 'hitCallback':
function(){
window.location = url;
}
});
这工作得很好,但有一个问题,一些用户(包括我自己)倾向于鼠标中/命令+点击大多数链接,以便在一个新的选项卡中打开它们。这显然不适用于上面的脚本。
我想知道是否有像event.triggerDefault()
这样的东西会把事件的控制交还给浏览器,或者如果我真的要建立一些东西来检测用户的鼠标中间/命令点击。
如何触发事件后使用event. preventdefault()和如何克隆或重新调度DOM事件的帮助?我想出了以下解决方案:
<script>
var anchor = document.getElementById('anchor');
anchor.addEventListener('click', function(e){
if(e.eventHandled) return;
e.preventDefault();
window.alert('Javascripts');
var clonedEvent = new e.constructor(e.type, e);
clonedEvent.initEvent(e.type, true, false);
clonedEvent.eventHandled = true;
anchor.dispatchEvent(clonedEvent);
});
</script>
<a href="http://www.google.com/" id="anchor">Google</a>
现在当命令+点击链接你首先收到警报,然后被发送到一个新的选项卡。
Jsfiddle: http://jsfiddle.net/8NRJY/1/(注意,如果您进行普通单击,Jsfiddle不会更改url,但在Jsfiddle之外可以正常工作)
现在剩下的就是使这个跨浏览器兼容,并插入谷歌跟踪(dispatchEvent将在回调中)。
编辑:这是跨浏览器(至少IE8+)兼容的版本。
如果你使用的是原生javascript,那么第一个函数应该是你的库的一部分。
<script>
var addEventListener = function(elem, eventName, handler, useCapture) {
if (elem!=null) {
if (elem.addEventListener) {
if (useCapture===true||useCapture===false) {
elem.addEventListener(eventName, handler, useCapture);
}
else {
elem.addEventListener(eventName, handler);
}
} else {
elem.attachEvent('on' + eventName, function(evt) {
evt = evt || window.event;
evt.target = evt.target || evt.srcElement;
handler(evt);
});
}
}
};
var onReady = function (fn) {
if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', fn);
} else {
document.attachEvent('onreadystatechange', function() {
if (document.readyState === 'interactive' || document.readyState === 'complete'){
fn();
}
});
}
};
var fireEvent = function(el, event){
if(document.createEvent){
var clonedEvent = new event.constructor(event.type, event);
clonedEvent.initEvent(event.type, true, false);
el.dispatchEvent(clonedEvent);
}else if(document.createEventObject){
var clonedEvent = document.createEventObject();
el.fireEvent('on'+event.type, clonedEvent);
}
};
onReady(function(){
var anchor = document.getElementById('anchor');
addEventListener(anchor, 'click', function(e){
if(!anchor.eventDispatched){
e.preventDefault ? e.preventDefault() : e.returnValue = false;
anchor.eventDispatched = true;
fireEvent(anchor, e);
}else{
anchor.eventDispatched = false;
e.returnValue = true;
}
});
});
</script>
<a id="anchor" href="http://www.google.com">Test</a>
编辑2:修复这个工作与谷歌分析被证明是一个比我想象的更艰巨的任务。
在现代浏览器中,它可以立即运行。在IE8中,一次只有一个事件(存储在window.event
中),这意味着谷歌的回调覆盖了它,这意味着我不能重新启动原始事件。我正在尝试各种克隆事件的方法,但到目前为止还没有成功。
我恨你IE8。
编辑3:我已经放弃尝试在IE8中使这个工作
编辑4:事实证明,Chrome阻止新窗口作为弹出,因为事件是在回调后触发的(即使它的原始用户点击事件)。
如果您想使用Google analytics来跟踪用户在内部链接上的导航,以下内容可能会有所帮助。
- 将Google Analytics (GA)事件数据存储在cookie中,但暂时不发送GA事件。
- 让DOM事件的默认行为执行
- 在下一页,读取cookie,查找排队的GA事件,并将它们发送给分析。
根据我的经验,cookie是在离开页面之前立即设置的。
要确保GA事件对应于报告中的正确页面,您应该执行以下操作将事件发送给GA:
var currentPage = window.location.pathname;
var previousPage = document.referrer.replace(/^[^:]+://[^/]+/, '').replace(/#.*/, '');
ga('set', 'page', previousPage);
ga(tracker, 'event', category, action, label, value, {
'hitCallback': function(){
ga('set', 'page', currentPage);
},
'nonInteraction': 1
});
回调为后续分析请求恢复页面值。非交互确保事件不会影响你的跳出率。