e.preventDefault();有多危险,可以用keydown / mousedown跟踪代替吗?

时间:2010-12-29 03:15:25

标签: javascript jquery javascript-events google-analytics analytics

我正在为一个相当复杂的CRM制作跟踪脚本,以跟踪Google Analytics中的表单操作。我正在尝试平衡跟踪表单操作的愿望与需求以永远不会阻止表单无法正常工作。

现在,我知道做这样的事情不起作用。

$('form').submit(function(){
 _gaq.push(['_trackEvent', 'Form', 'Submit', $(this).attr('action')]);
});

在有机会处理之前,DOM会卸载。

因此,很多示例代码推荐如下:

$('form').submit(function(e){
e.preventDefault();
var form = this; 
 _gaq.push(['_trackEvent', 'Form', 'Submit', $(this).attr('action')]);
//...do some other tracking stuff...
setTimeout(function(){
form.submit();
}, 400);
});

most cases这是可靠的,但这让我很紧张。如果e.preventDefault();之间发生某些事情并且当我开始触发基于DOM的提交时会发生什么?我完全打破了这个形式。

我一直在探索其他一些分析实现,我注意到something like this

$('form').mousedown(function(){
 _gaq.push(['_trackEvent', 'Form', 'Submit', $(this).attr('action')]);
});
$('form').keydown(function(e){
    if(e.which===13) //if the keydown is the enter key
    _gaq.push(['_trackEvent', 'Form', 'Submit', $(this).attr('action')]);
});

基本上,代替中断的形式提交,通过假设如果有人向下移动鼠标或键入向下上输入,比表单提交抢占它。显然,这会造成一定的误报,但它完全消除了使用e.preventDefault();,这在我的脑海里消除了我可能永远阻止形式从成功提交的风险。

所以,我的问题:

  • 是否可以采用标准 表单跟踪代码段并阻止它 从永远完全阻止表格 提交?
  • 是 mousedown / keydown替代可行吗?
  • 是否有可能错过的提交案例?具体来说,除了鼠标和键盘之外还有其他方式可以提交吗?在开始卸载页面之前,浏览器是否总是有时间处理javascript?

7 个答案:

答案 0 :(得分:30)

他们对那里的谷歌非常聪明,而且他们有时会想到某些事情,因为这肯定会发生,现在,确实如此。你为什么不试试这个:

$('form').submit(function(e){
  e.preventDefault();
  var form = this; 
  _gaq.push(['_trackEvent', 'Form', 'Submit', $(this).attr('action')]);
  //...do some other tracking stuff...
  _gaq.push(function(){
     form.submit();
    });
  });

_gaq.push thigamajigger按顺序执行其元素,所以你应该开玩笑。

不,我不知道为什么我突然开始这么说。

答案 1 :(得分:3)

我使用不同的方法,并在提交的页面中生成事件跟踪脚本。您可以将其称为延迟事件跟踪

我写了一个blog post,其中包含有关我在后端操作中跟踪事件的方法的所有详细信息。它偏向于Java-Struts,但你可以得到一般的想法。

理由是我想在服务器端发生一些事情后跟踪它们。在这种情况下,表单由服务器提交并处理后。

我做了什么(非常总结):

  • 将事件存储在与会话关联的对象(列表/队列)中
  • 在下一页渲染时刷新这些事件(生成javascript并清空队列)

答案 2 :(得分:3)

如果您必须让表格始终有效,但如果绝对必要,可以牺牲跟踪,您可以尝试/抓住它。

$('form').submit(function(e){
    try{
        e.preventDefault();
        var form = this; 
         _gaq.push('_trackEvent', 'Form', 'Submit', $(this).attr('action'));
        //...do some other tracking stuff...
        setTimeout(function(){
            form.submit();
        }, 400);
    } catch (e) {
        form.submit();
    }
});

答案 3 :(得分:1)

e.preventDefault()不必在函数调用的开头就正确。为什么不只是有一个if语句来验证一切是否正常工作,如果有的话只调用e.preventDefault()。如果链中的任何函数未返回预期结果,请将submitted变量设置为false,并且不要阻止默认值。

当涉及到任何异步(例如你的setTimeout时,这可能会更难处理,但是会有很多方法可以确定,具体取决于代码的样子。所以你可以查看如果方法存在if (_gaq.push)(例如)。如果没有在每个浏览器中测试每个组合,你就无法100%确定,但我认为你可以得到一个非常令人满意的结果。

答案 4 :(得分:0)

另一种方法:

var pageTracker;
_gaq.push(function() {
    pageTracker = _gat._getTrackerByName();
});

$('form').submit(function(e){
    pageTracker._trackEvent('Form', 'Submit', $(this).attr('action'));
};

我猜这种方式_trackEvent会同步,但我还没有测试过它。

答案 5 :(得分:0)

您是否有理由不能根据收到的POST从服务器端发出对Google Analytics的调用?

我不知道你的系统是什么内置的,但是例如,这个PHP项目会发出对GA的调用,从而消除了DOM卸载的问题,需要打破表单等等。 / p>

http://code.google.com/p/serversidegoogleanalytics/

我意识到您可能需要捕获一个cookie - 您可能会在提交之前将该值写入表单中的隐藏字段?

答案 6 :(得分:0)

扩展@ Malvolio的答案: gaq发送事件后,队列中的下一个项目将处理。这意味着事件HTTP请求可能在客户端中止,但GA将接收请求。在响应完成之前,不要担心阻止脚本执行。这是一场火灾和遗忘的场景。