Javascript 当onclick事件执行异步代码时,如何执行在新选项卡请求中打开?

Javascript 当onclick事件执行异步代码时,如何执行在新选项卡请求中打开?,javascript,asynchronous,callback,google-analytics,Javascript,Asynchronous,Callback,Google Analytics,设置 我实现了一个“onclick”方法,该方法异步调用一些第三方代码。它提供了一个回调,他们建议使用一个简单的函数设置document.location=href,以确保页面仅在其方法返回后更改。如果要在同一选项卡中打开链接,此操作很好,但如果要在新选项卡中打开链接,则会发生以下两种情况之一: 问题 如果单击鼠标中键、Ctrl+click、Shift+click或Cmd+click,则在执行回调函数后将在同一选项卡中打开 如果右键单击并选择“在新选项卡中打开”,则根本不会调用onclick代码

设置

我实现了一个“onclick”方法,该方法异步调用一些第三方代码。它提供了一个回调,他们建议使用一个简单的函数设置
document.location=href
,以确保页面仅在其方法返回后更改。如果要在同一选项卡中打开链接,此操作很好,但如果要在新选项卡中打开链接,则会发生以下两种情况之一:

问题

  • 如果单击鼠标中键、Ctrl+click、Shift+click或Cmd+click,则在执行回调函数后将在同一选项卡中打开
  • 如果右键单击并选择“在新选项卡中打开”,则根本不会调用onclick代码
  • 问题

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

    代码

    :

    
    //单击指向产品的链接时调用。
    函数单击(){
    ga(‘ec:addProduct’{
    'id':'P12345',
    “姓名”:“安卓沃霍尔T恤”,
    “类别”:“服装”,
    “品牌”:“谷歌”,
    “变体”:“黑色”,
    “位置”:1
    });
    ga('ec:setAction','click',{list:'Search Results'});
    //发送带有事件的单击,然后将用户发送到产品页面。
    ga(‘发送’、‘事件’、‘用户体验’、‘点击’、‘结果’{
    “hitCallback”:函数(){
    document.location='/product_details?id=P12345';
    }
    });
    }
    
    这是一个棘手的问题,在我的职业生涯中我不得不多次解决。我采取了各种方法,在这个回答中,我将尝试总结我的最新想法:

    不阻止默认设置。

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

    就我个人而言,我认为最好还是让浏览器来完成它的工作,然后想出另一种方法来完成你想做的事情

    使
    ga()
    函数同步。

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

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

    analytics.js最近推出,它允许您覆盖或修改库的各种内置行为。下面是一个如何覆盖
    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');
    
    注意,我还没有测试过这段代码,但我认为它应该可以工作。而且,如果不明显,您必须自己实现
    wasExternalLinkClicked()
    ,但这应该不会太难


    无论如何,希望这能帮上忙

    我将研究看起来很有希望的任务
    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');