Google 跟踪代码管理器的内置点击触发器和阴影问题 -dom
Issues with Google Tag Manager's built in Click trigger and shadow-dom
Google 跟踪代码管理器 (GTM) 具有内置的点击触发器,可让您在用户点击内容时触发 GTM 代码。
我相信它是通过在文档上添加一个 'click' 侦听器,然后在进行点击时将一个特殊的 'gtm.click' 事件推送到数据层来实现的。
在推入 dataLayer 的 'gtm.click' 对象中,GTM 包含从 event.target 属性 中提取的某些数据,包括目标元素的属性,例如 id/class/href。
问题是...
如果您正在使用 shadow-dom in your html the target/data will be wrong. This is due to the fact that when events bubble up through shadow-dom boundaries they "are re-targeted to look like they've come from the component rather than the internal elements within your shadow DOM"。
如果您根据事件目标数据在 GTM 中创建 tags/triggers/variables 并且您希望该目标是用户实际点击的元素(这看起来很正常),这可能会出现问题.
是否已有解决方案?
理想情况下 GTM 会在内部解决这个问题;在那之前,这是我想出的解决方案...
创建一个文档级点击侦听器(就像 GTM 一样)并触发自定义点击事件,但数据来自原始事件目标(而不是重新定位的目标)。
因此,在文档中侦听 'click',然后使用 event.composedPath()[0]
或不支持 composedPath 的浏览器的回退之一获取原始目标。我只是在查看不同的文档并在不同的浏览器中尝试将其拼凑在一起,所以不确定它是否完美。
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);
我最初考虑使用 'event': 'gtm.click'
模拟 GTM 内置点击事件,但后来我得出结论,这可能不是最好的主意.. hacky,会导致需要过滤的重复事件,并且会让不知道发生了什么的人感到困惑。虽然我认为可以使用内置的 GTM 变量,如 'gtm.elementClasses': target.className || ''
、'gtm.elementId': target.id || ''
、'gtm.elementTarget': target.target || ''
、'gtm.elementUrl': target.href || target.action || ''
等
Google 跟踪代码管理器 (GTM) 具有内置的点击触发器,可让您在用户点击内容时触发 GTM 代码。
我相信它是通过在文档上添加一个 'click' 侦听器,然后在进行点击时将一个特殊的 'gtm.click' 事件推送到数据层来实现的。
在推入 dataLayer 的 'gtm.click' 对象中,GTM 包含从 event.target 属性 中提取的某些数据,包括目标元素的属性,例如 id/class/href。
问题是...
如果您正在使用 shadow-dom in your html the target/data will be wrong. This is due to the fact that when events bubble up through shadow-dom boundaries they "are re-targeted to look like they've come from the component rather than the internal elements within your shadow DOM"。
如果您根据事件目标数据在 GTM 中创建 tags/triggers/variables 并且您希望该目标是用户实际点击的元素(这看起来很正常),这可能会出现问题.
是否已有解决方案?
理想情况下 GTM 会在内部解决这个问题;在那之前,这是我想出的解决方案...
创建一个文档级点击侦听器(就像 GTM 一样)并触发自定义点击事件,但数据来自原始事件目标(而不是重新定位的目标)。
因此,在文档中侦听 'click',然后使用 event.composedPath()[0]
或不支持 composedPath 的浏览器的回退之一获取原始目标。我只是在查看不同的文档并在不同的浏览器中尝试将其拼凑在一起,所以不确定它是否完美。
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);
我最初考虑使用 'event': 'gtm.click'
模拟 GTM 内置点击事件,但后来我得出结论,这可能不是最好的主意.. hacky,会导致需要过滤的重复事件,并且会让不知道发生了什么的人感到困惑。虽然我认为可以使用内置的 GTM 变量,如 'gtm.elementClasses': target.className || ''
、'gtm.elementId': target.id || ''
、'gtm.elementTarget': target.target || ''
、'gtm.elementUrl': target.href || target.action || ''
等