Google跟踪代码管理器内置的Click触发器和shadow-dom的问题

dev*_*lop 5 shadow-dom google-tag-manager

Google跟踪代码管理器(GTM)具有内置的Click触发器,可让您在用户点击内容时触发GTM代码.

我相信它是通过在文档上添加"click"侦听器然后在进行点击时将特殊的"gtm.click"事件推送到dataLayer来实现的.

在推送到dataLayer的'gtm.click'对象中,GTM包含从event.target属性中提取的某些数据,包括目标元素的属性,例如id/class/href.

问题是......

如果你在html中使用shadow-dom,目标/数据将是错误的.这是因为当事件通过阴影 - 边界边界冒泡时,它们"被重新定位为看起来像是来自组件而不是阴影DOM中的内部元素".

如果您在GTM中根据事件目标数据创建标签/触发器/变量,并且您希望该目标是用户实际点击的元素(这看起来很正常),则可能会出现问题.

是否存在已存在的解决方案?

dev*_*lop 5

理想情况下,GTM 会在内部解决这个问题;在那之前,这是我想出的解决方案......

创建一个文档级点击侦听器(就像 GTM 一样)并触发自定义点击事件,但使用从原始事件目标(而不是重新定位的目标)中提取的数据。

因此,请听文档上的“单击”,然后使用event.composedPath()[0]不支持组合路径的浏览器的后备或后备之一获取原始目标。我只是拼凑起来查看不同的文档并在不同的浏览器中尝试,所以不确定它是否完美。

function getOriginalTarget(ev) {
  if ('composedPath' in ev) return ev.composedPath()[0]; // Standard
  else if ('path' in ev) return ev.path[0]; // Old Chrome
  else if ('originalTarget' in ev) return ev.originalTarget; // Firefox
  else if ('srcElement' in ev) return ev.srcElement; // Old IE & Safari
  else return ev.target; // Fallback to normal target.
};

document.addEventListener('click', function (ev) {
  var target = getOriginalTarget(ev);

  dataLayer.push({
    'event': 'MyClick', // some custom event
    'targetId: target.id || '' // some custom data (from original target)
    // etc...
  });
}, false);
Run Code Online (Sandbox Code Playgroud)

我最初考虑使用模拟 GTM 内置点击事件,'event': 'gtm.click'但后来我得出结论,这可能不是最好的主意.. hacky,会导致需要过滤的重复事件,并且会让不知道的人感到困惑发生了什么事。虽然我认为一个人可以使用内置的GTM变量,如'gtm.elementClasses': target.className || '''gtm.elementId': target.id || '''gtm.elementTarget': target.target || '''gtm.elementUrl': target.href || target.action || '',等。