当onclick事件执行异步代码时,如何在新选项卡请求中使用Open?

nac*_*ito 5 javascript asynchronous google-analytics callback

设置

我已经实现了一个"onclick"方法,它可以异步调用一些第三方代码.它提供了一个回调,他们建议使用一个简单的函数来设置document.location = href,以确保页面只在它们返回方法后发生变化.如果要在同一选项卡中打开链接,这可以正常工作,但如果要在新选项卡中打开,则会发生以下两种情况之一:

问题

  1. 如果您在执行回调函数后单击中键,Ctrl +单击,Shift +单击或Cmd +单击它将在同一选项卡中打开.
  2. 如果右键单击并选择"在新选项卡中打开",则根本不会调用onclick代码.

问题

是否有可能让回调函数对onclick事件返回true(实际上,使整个事件链同步)?或者,您能想到在上面的案例1中保留标准浏览器行为的方法吗?

代码

https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce:

<a href="/product_details?id=P12345" onclick="clicked(); return !ga.loaded;">Product Link</a>

<script>
// Called when a link to a product is clicked.
function clicked() {
  ga('ec:addProduct', {
    'id': 'P12345',
    'name': 'Android Warhol T-Shirt',
    'category': 'Apparel',
    'brand': 'Google',
    'variant': 'black',
    'position': 1
  });
  ga('ec:setAction', 'click', {list: 'Search Results'});

  // Send click with an event, then send user to product page.
  ga('send', 'event', 'UX', 'click', 'Results', {
      'hitCallback': function() {
        document.location = '/product_details?id=P12345';
      }
  });
}
</script>
Run Code Online (Sandbox Code Playgroud)

Phi*_*ton 1

这是一个棘手的问题,在我的职业生涯中我不得不多次解决。我采取了各种方法,在这个答案中我将尝试总结我的最新想法:

不阻止违约。

当您阻止浏览器执行默认操作时,您最终必须自己重新编码,并且手动处理用户意图和浏览器/平台变化的所有可能组合会变得非常棘手。这不值得。有些事情(例如检查按下了哪些键)可以被解释,但还有其他事情(例如用户右键单击并选择“在新选项卡中打开”)基本上无法检测到。

就我个人而言,我认为最好让浏览器完成它的任务,然后找出另一种方法来完成您想要做的事情。

使ga()功能同步。

在您提供的示例代码中,您尝试在用户单击链接时将电子商务和事件点击发送到 Google Analytics(分析)。问题在于该ga()调用是异步的,因此如果用户单击链接,则该调用可能会也可能不会在浏览器加载新页面之前完成。

一种可能的解决方案是覆盖analytics.js发送点击的方式,使其同步而不是异步。这将允许您发送点击,而不必阻止事件默认并处理手动打开链接。

Analytics.js 最近引入了Tasks,它允许您覆盖或修改库的各种内置行为。以下是如何重写以sendHitTask实现同步版本的示例:

ga('create', 'UA-XXXX-Y', 'auto');

ga(function(tracker) {

  // Grab a reference to the default sendHitTask function.
  var originalSendHitTask = tracker.get('sendHitTask');

  // Modify the send hit task to be sync in cases where an
  // external link was clicked.
  tracker.set('sendHitTask', function(model) {
    if (wasExternalLinkClicked()) {
      var xhr = new XMLHttpRequest();
      var url = '//www.google-analytics.com/collect?' + model.get('hitPayload');
      // Specifying `false` as the third parameter makes the request sync.
      xhr.open('GET', url, false);
      xhr.send();
    } else {
      originalSendHitTask(model);
    }
  });
});

ga('send', 'pageview');
Run Code Online (Sandbox Code Playgroud)

请注意,我还没有测试过这段代码,但我认为它应该可以工作。而且,如果它不明显,您就必须wasExternalLinkClicked()自己实现,但这应该不会太困难。

无论如何,希望有帮助!