点击表单提交后在谷歌分析中跟踪事件

64
我需要跟踪当某人填写表格并点击提交时在Google Analytics中的事件。生成的页面是标准的仪表板类型页面,因此为了在该页面上跟踪事件,我必须在URL中传递事件,然后读取URL并基于它输出Google Analytics事件跟踪JavaScript代码。但这是一个常常被收藏的页面,也是一个会被重新加载、回退等的页面,因此我真的不想在URL中传递跟踪事件并破坏分析。

相反,我宁愿在具有表单的页面上使用以下jQuery代码:

$('#form_id').submit(function() {
  _gaq.push('_trackEvent', 'my category', 'my action');
});

我担心上述方法会错过一些事件的跟踪,因为在调用该JavaScript之后,浏览器会立即提交表单并转到另一个网页。如果 utm.gif 跟踪图像没有及时加载,我就会错过事件 :(。

我的担忧是否合理?我该如何确保不会错过要跟踪的事件?


1
你会错过事件的,是的:我也遇到了这个问题。如果表单正在POST信息,则该POST请求将覆盖向GA报告事件的Google Analytics GET请求(并导致Chrome控制台中的加密错误 -至少在11.0.696.65中)。 - lucasrizoli
9个回答

146

使用Google Analytics hitCallback

您可以在跟踪器对象上指定自定义回调函数。

_gaq.push(['_set', 'hitCallback', function(){}]);

“hit is sent successfully.”之后会调用回调函数。

如果您想要跟踪提交按钮的点击并在发送表单后进行此操作,则可以使用以下代码(使用jQuery):

var _this = this; // The form input element that was just clicked
_gaq.push(['_set','hitCallback',function() {
    $(_this).parents('form').first().submit(); // Submit underlying form
}]);
_gaq.push(['_trackEvent', 'My category', 'My action']);
return !window._gat; // Ensure that the event is bubbled if GA is not loaded

或者作为 <input type="submit"> 元素的单行代码:onclick

onclick="var _this=this;_gaq.push(['_set','hitCallback',function(){$(_this).parents('form').first().submit();}]);_gaq.push(['_trackEvent','My category','My action']);return !window._gat;"
它的作用是跟踪事件 My category/My action,使用jQuery查找刚刚推送的提交按钮底下的表单元素,然后提交整个表单。参见: Google Analytics-发送数据到Google Analytics-Hit Callback(感谢supervacuo) 更新内容:如果您正在使用带有定义ga()函数的现代analytics.js代码,则可以编写以下内容:
var _this = this;
ga('send', 'event', 'My category', 'My action', {
    'hitCallback': function() {
        $(_this).parents('form').first().submit();
    }
});

return !window.ga;

12
这个方法很好用,但我发现需要在它触发后通过 _gaq.push(['_set', 'hitCallback', null]); 清除回调函数,否则如果用户点击“返回”按钮,然后在页面上执行其他操作引起另一个 _gaq.push 的话,回调函数会再次触发。在 Android 上,我必须这样做才能防止回调函数被错误地触发多次。 - George Armhold
@CaffeineComa 为我省了大量的调试时间!!!虽然 Google 可能不再支持 ga.js,但我想知道为什么他们在执行后没有自己清除回调函数。 - Gilad Peleg
@renfei,你确定在这些情况下hitCallback永远不会触发吗?文档指定,“此回调函数旨在始终被调用,无论是在成功发送命中后直接调用,还是在确定无法发送命中或发送失败时调用。” https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#hitCallback - d3vin
5
如果阻止了google-analytics.js,那该怎么办?虽然仍然定义了ga,但回调函数将无法工作。我已经添加了下面的情况(适用于Google Analytics Universal),如果您能更新您的答案将非常好(这将节省其他人的时间)。无论如何,感谢您提供的答案! - Dmytro Pastovenskyi
1
@DmytroPastovenskyi 这是每个人在查看这个答案时都应该注意的关键点。 - BadHorsie
显示剩余7条评论

18

确保所有表单提交(在启用JS且未阻止GA的用户中)100%的方法只有两种:

  • 您可以执行AJAX提交,然后无需担心页面更改,因此拥有足够的时间让GA处理并在旧页面的位置加载新页面。
  • 您可以强制表单在新窗口中打开其操作,从而使主页面上的所有后台进程工作,并防止您担心的竞争条件。

这是因为Google Analytics没有回调函数,因此即使您设置了10秒延迟,也无法确定您是否捕获了所有提交。

或者,您可以将GET值传递给提交的页面,并在该页面上设置值的检查。如果已设置,则可以发送trackEvent调用。


新窗口不是选项。然而,AJAX方法如何帮助呢?在谷歌分析图像加载的同时,我将如何能够打开新页面以代替旧页面? - at.
1
从技术上讲,它将是相同的页面,只是使用JavaScript动态加载新内容,根据结果,为最终用户“感觉”像一个新页面。但是,由于在ga.js构建__utm.gif请求之前该页面不会离开,因此没有中断的机会,因此这将提供更准确的提交数量视图。 - Yahel
@yc 谢谢,现在我明白你的意思了。嗯...这个网站非常依赖链接、点击返回按钮和其他一些让我非常注意每个视图和操作都有一个单独的网页。不过,我想我们可以将URL更改为类似于 /current_form_page#redirect=new_page 的东西。任何ajax提交都会用新页面替换整个<body>并相应地设置URL。直接转到该URL或重新加载会导致重定向到指定页面。不确定会出现什么问题,但我会给你采纳的答案。 - at.
6
对于未来遇到此问题的谷歌用户,现在Google Analytics确实有回调函数。只需在最后一个参数处传递一个对象,其中包含一个名为hitCallback的属性,其值为一个函数即可。 - coredumperror

12

对于那些使用Google Analytics Universal并在hitCallback上进行某些操作(例如,在表单验证之后但提交之前跟踪事件)的人,请记住,google-analytics.js可能会被阻止,但ga函数仍将被定义,因此提交不会发生。

ga('send', 'pageview', event, {
  'hitCallback': function() {
    _this.submit();
  }
})
return !window.ga;

可以通过检查ga是否已经加载来修复。

ga('send', 'pageview', event, {
  'hitCallback': function() {
    _this.submit();
   }
})
return !(ga.hasOwnProperty('loaded') && ga.loaded === true)

1
这段代码是否应该包装在一个函数中?我不明白那个孤零零的return语句是什么意思。我错过了什么吗?谢谢。 - Julián Landerreche

7
这个问题已经几年了,而且似乎谷歌分析提供了一种方法来完成这个功能,无需使用上面提供的技巧。
谷歌分析文档中可以看到:

除了命令数组之外,您还可以将函数对象推送到_gaq队列。这些函数可以包含任意的JavaScript代码,并且与命令数组一样,它们按照被推送到_gaq的顺序执行。

您可以将此与多个命令推送结合使用,以确保它们按顺序添加(并节省调用)。
$('input[type="submit"]').click(function(e) {
    // Prevent the form being submitted just yet
    e.preventDefault();

    // Keep a reference to this dom element for the callback
    var _this = this;

    _gaq.push(
        // Queue the tracking event
        ['_trackEvent', 'Your event', 'Your action'],
        // Queue the callback function immediately after.
        // This will execute in order.
        function() {
            // Submit the parent form
            $(_this).parents('form').submit();
        }
    );
});

这样行得通吗?看起来它首先会跟踪事件,加载 utm.gif 图像。然后它将提交表单,但在 utm.gif 加载之前仍有可能表单将您带到另一个页面(无论需要加载多少才能注册事件)。 - at.
经进一步调查,这个SO答案提供了一些见解,但最终似乎存在不确定性:https://dev59.com/XXA75IYBdhLWcg3wMl8Z#5250446。无论GA脚本实际上是如何做的,该页面上有一些其他值得关注的建议。 - epocsquadron
另一个类似的回答表明这是不可能的:https://dev59.com/mWsz5IYBdhLWcg3wCDl2#8147110 - epocsquadron
另外需要注意的是:在离开页面之前,GA调试器会报告成功。 - epocsquadron
这段代码不起作用,因为函数将立即执行,而不等待事件被跟踪。 - Eugene Fidelin

6
如果你不太在意100%的准确性,你可以只加一个1秒的延迟。
$('#form_id').submit(function(e) {
  var form = this;
  e.preventDefault(); // disable the default submit action

  _gaq.push('_trackEvent', 'my category', 'my action');

  $(':input', this).attr('disabled', true); // disable all elements in the form, to avoid multiple clicks

  setTimeout(function() { // after 1 second, submit the form
    form.submit();
  }, 1000);
});

1
思考一下,即使HTTP请求未完成,这将几乎100%准确。关键事件是Google服务器接收到请求,HTTP请求的完成仅用于客户端反馈。1秒钟将为您提供非常接近100%的准确性。 - lonesomeday
@lonesomeday 这不会创建一个无限循环吗?在结尾调用formsubmit()不会一遍又一遍地调用这个函数吗? - Yahel
1
@yc 不行,因为那是 DOM 元素的提交动作,而不是 jQuery 对象的,因此它不会调用 jQuery 处理程序。 - lonesomeday
@lonesomday 嗯,你说得没错,但并不是100%准确。延迟在于生成HTTP请求。GA不会立即执行它,而是首先在JavaScript中生成请求。通常很快,但在边缘情况的浏览器上仍然是不可预测的。 - Yahel
@yc 有趣的是,我对GA并不是特别熟悉,当然也不熟悉其中的这个部分。我不太明白这会如何改变关于准确性的观点 - 毕竟几乎没有浏览器需要一秒钟来生成HTTP请求。 - lonesomeday
@lonesomeday GA以异步方式发送这些事件,因此无法知道它们何时被发送。如果有太多事件排队,或者浏览器正在忙于计算其他内容,则可能需要一段时间。重点是无法确切知道事件将在何时发送。对于网站的常规分析来说,这可能是可以接受的,但对于NASA(或关键任务的统计数据)来说则不行。 - elliottregan

6

虽然 hitCallback 解决方案不错,但我更喜欢设置一个 cookie 并在下一页触发事件。这样,GA 中的故障不会影响我的网站:

// Function to set the event to be tracked:
function setDelayedEvent(category, action, label, value) {
  document.cookie='ev='+escape(category)+'!'+escape(action)+'!'+escape(label)+'!'+value
      +'; path=/; expires='+new Date(new Date().getTime()+60000).toUTCString();
}

// Code run in every page, in case the previous page left an event to be tracked:
var formErrorCount= formErrorCount || 0;
var ev= document.cookie.match('(?:;\\s*|^)ev=([^!]*)!([^!]*)!([^!]+)!([^!]+)(?:;|\s*$)');
if (ev && ev.length>2) {
  _gaq.push(['_trackEvent', unescape(ev[1]), unescape(ev[2]),
     unescape(ev[3]), parseInt(ev[4])]);
  document.cookie='ev=; path=/; expires='+new Date(new Date().getTime()-1000).toUTCString();
}

2
这是在gtag.js中进行事件回调的方法,以确保在更改页面URL之前发送Google Analytics数据:
gtag('event', 'view_promotion', { myParameter: myValue, event_callback: function () {
    console.log('Done!');
    // Now submit form or change location.href
} });

来源:https://developers.google.com/analytics/devguides/collection/gtagjs/sending-hits

这是一篇介绍如何发送Google Analytics数据的文档。它涉及使用gtag.js库收集网站和移动应用程序的数据,并将其发送到Google Analytics帐户以进行报告和分析。

1

好的,既然我们已经转向使用Universal Analytics,我想用GTM和UA来回答同样的问题。


GTM

使用GTM在点击表单提交时跟踪Google Analytics事件非常容易。

  • 在GTM中创建UA标签,并将类型设置为event
  • 填写所需的事件操作、类别和标签。
  • 创建表单提交类型的触发器。
  • 添加更多条件以定位所需的按钮。

这是最佳、最优和最简单的方法,适用于OP。

enter image description here


0

当每个提交都需要跟踪时,我通常在后端设置一个带有所有必需数据的cookie。然后在GTM中设置一个规则,根据此第一方cookie的存在触发标签。标签解析所需值的cookie并执行所需操作,然后删除cookie。

更复杂的例子是购买跟踪。 当用户执行购买时,您想要触发5个不同的标签。竞争条件和立即重定向到某个欢迎页面使得依赖简单的“onSubmit”跟踪变得困难。因此,我使用包含所有购买相关数据的cookie,并且在用户最终停留的任何页面上,GTM将识别cookie,触发“入口点”标签,该标签将解析cookie,将所有值推送到dataLayer,删除cookie,然后标签本身将推送事件到dataLayer,从而触发需要购买数据(已经在dataLayer中)的5个标签。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接