e.preventDefault();有多危险,可以用键盘按下/鼠标按下跟踪来代替吗?

问题描述 投票:7回答:7

我正在为一个相当复杂的CRM编写跟踪脚本,以跟踪Google Analytics(分析)中的表单操作。我试图用need平衡准确跟踪表单操作的需​​求,以永不阻止表单不起作用。

现在,我知道做这样的事情是行不通的。

$('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')]);
});

[基本上,不是中断表单提交,而是假设有人在Enter上按下鼠标或按下Enter键,然后提交该表单,以此来抢先提交。显然,这将导致一定数量的误报,但它完全消除了e.preventDefault();的使用,在我看来,这消除了我可能永远无法成功提交表单的风险。

所以,我的问题:

  • 是否可以采用标准表单跟踪代码段并防止它从ever完全阻止该形式从提交?
  • 是mousedown / keydown替代可行吗?
  • 是否有任何可能遗漏的提交案例?具体来说,除了鼠标和键盘输入以外,还有其他方法可以最终提交吗?浏览器在开始卸载页面之前会一直有时间处理javascript吗?
javascript jquery google-analytics analytics jquery-events
7个回答
30
投票

他们在那附近的Googleplex的惨淡经历使他们感到沮丧,他们想了一天这样的事情一定会发生,而现在,果然如此。您为什么不尝试一下呢:

$('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会顺序执行其元素,所以应该没事。

不,我不知道为什么我突然开始这样讲话。


3
投票

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

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

理由是,我想跟踪某些事情在服务器端发生之后。在这种情况下,服务器提交表单并对其进行处理之后。

我做什么(非常摘要):

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

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();
    }
});

1
投票

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

当涉及到任何异步内容(例如setTimeout时,这可能会更难处理,但根据代码的样子,有很多方法可以确定)。因此,您可以检查方法是否存在例如,使用if (_gaq.push)。如果不测试每个浏览器中的每个组合,就无法100%确定,但是我认为您可以通过此方法获得令人满意的结果。


0
投票

另一种方法:

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

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

我想_trackEvent这样会是同步的,但我尚未对其进行测试。


0
投票

有没有原因,您不能仅基于服务器收到的POST从服务器端发出对Google Analytics(分析)的调用?

我不知道您的系统内置什么,但是,例如,这个PHP项目将发出对GA的调用,从而消除了DOM卸载,破坏表格的需要,等等。

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

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


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.