最佳实践
首先,使用 Shadow DOM 概念的精神是为 Web 组件提供作用域/闭包,这样人们就不能只是去戳它们并搞砸它们。原则上,它类似于在更高范围无法触及的函数内部具有局部范围变量。在实践中,可以绕过这堵“墙”并随心所欲,但它打破了影子 DOM 的“精神”,这在 IMO 是不好的做法。
所以,如果我要就此提出一些最佳实践,我的第一个建议是尽可能尊重使用影子 DOM 的 Web 组件的精神,并将它们视为他们努力成为的黑匣子.这意味着,您应该去找负责 Web 组件的 Web 开发人员,并要求他们提供一个界面供您使用。
例如,Adobe Launch 能够侦听广播到(轻)DOM 的自定义事件,因此网站开发人员可以添加到他们的 Web 组件、创建自定义事件并在单击按钮时广播它。
注意: Launch 的自定义事件监听器只会监听从 document.body 开始的自定义事件广播,不是 document,所以一定要在document.body 或更深的地方创建和广播自定义事件。
“但是开发人员不会做任何事情,所以我必须自己处理事情......”
可悲的是,这往往是一个现实,所以你必须做你必须做的事。如果是这种情况,那么,Launch 目前没有任何本机功能可以在这方面真正让您的生活更轻松(无论如何,对于以下内容的“核心”部分),并且在这篇文章中,AFAIK 有也没有为此提供任何东西的公共扩展。但这并不意味着你是 SoL。
但我想声明,我不确定我是否会很快将此答案的其余部分称为“最佳实践”,而不是“这是 'a' 解决方案..”。主要是因为这主要涉及将大量纯 javascript 转储到自定义代码框中并称之为一天,这更像是一种“万能的,最后的手段”解决方案。
同时,一般来说,在标签管理器方面最好避免使用自定义代码框,除非您必须这样做。标签管理器的全部意义在于抽象出代码。
我认为这里的 TL;DR 基本上是我重申这一点,理想情况下应该放在网站开发人员的盘子上去做。但是,如果您仍然因为 ReasonsTM 真的需要在 Launch 中完成所有操作,请继续阅读。
'A' 解决方案...
注意:这是一个非常简单的开放模式影子 DOM 场景的基本示例 - 实际上,您的场景几乎可以肯定要复杂得多。如果您正在深入研究,我希望您知道您在使用 javascript 做什么!
假设您在页面上有以下内容。自定义 html 元素的简单示例,其中添加了一个按钮到其影子 DOM。
<script>
class MyComponent extends HTMLElement {
constructor() {
super();
this._shadowRoot = this.attachShadow({
mode: 'open'
});
var button = document.createElement('button');
button.id = 'myButton';
button.value = 'my button value';
button.innerText = 'My Button';
this._shadowRoot.appendChild(button);
}
}
customElements.define('my-component', MyComponent);
</script>
<my-component id='myComponentContainer'></my-component>
假设您想在访问者点击按钮时触发规则。
快速解决方案示例
在这一点上,我可能应该说,您可以使用查询选择器my-component#myComponentContainer 执行启动点击事件规则并使用自定义代码条件,如下所示:
return event.nativeEvent.path[0].matches('button#myButton');
这样的事情应该适用于这种情况,因为这里有很多星星对齐:
- shadow dom 是开放模式,所以没有黑客来覆盖东西
- 对于光照和阴影 DOM 级别都有易于识别的唯一 css 选择器
- 您只想监听 click 事件,它会冒泡并
就像在 shadow root 的 light DOM root 上发生了点击一样。
但实际上,您的要求可能不会这么简单。也许您需要附加一些其他事件侦听器,例如视频播放事件。不幸的是,目前还没有“一刀切”的解决方案。这仅取决于您的实际跟踪要求。
但总的来说,目标与您要求开发人员做的几乎相同:在影子 DOM 的上下文中创建和广播自定义(轻)DOM 事件。
更好的解决方案示例
使用与上述相同的组件示例和要求,您可以例如创建一个规则以在 DOM 就绪时触发。将其命名为“我的组件跟踪 - 核心”或其他名称。没有条件,除非您想检查 Web 组件的根轻 DOM 元素是否存在等。
总的来说,这是将事件侦听器附加到按钮并调度自定义事件以供 Launch 侦听的核心代码。请注意,此代码基于我们上面的示例组件和跟踪要求。这个例子是独一无二的。您将需要根据自己的设置编写类似的代码。
添加一个自定义 js 容器,其中包含以下内容:
// get the root (light dom) element of the component
var rootElement = document.querySelector('#myComponentContainer');
if (rootElement && rootElement.shadowRoot) {
// get a reference to the component's shadow dom
var rootElementDOM = rootElement.shadowRoot;
// try and look for the button
var elem = rootElementDOM.querySelector('button#myButton');
if (elem) {
// add a click event listener to the button
elem.addEventListener('click', function(e) {
// optional payload of data to send to the custom event, e.g. the button's value
var data = {
value: e.target.value
};
// create a custom event 'MyButtonClick' to broadcast
var ev = new CustomEvent('MyButtonClick', {
detail: data
});
// broadcast the event (remember, natively, Launch can only listen for custom events starting on document.body, not document!
document.body.dispatchEvent(ev);
}, false);
}
}
从这里,您可以创建一个监听自定义事件广播的新规则。
自定义事件规则示例
规则名称:我的按钮点击次数
活动
扩展:核心
事件类型:自定义事件
名称:MyButtonClick
自定义事件类型:MyButtonClick
匹配 CSS 选择器的元素:body
条件
*此场景无*
从这里,您可以设置任何您想要的操作(设置 Adobe Analytics 变量、发送信标等)。
注意:
在这个例子中,我向自定义事件发送了一个数据负载。您可以使用event.detail 在任何自定义(javascript)代码框中引用有效负载,例如event.detail.value。您还可以使用 % 语法在 Launch 字段中引用它们,例如%event.detail.value%.