我们正在跟踪一个具有使用Shadow DOM概念构建组件的网站,当我们在启动时创建规则以向这些组件添加标记时,该站点将无法正常运行。
您可以为我们提供有关Shadow DOM中标记组件的最佳实践吗?
我发现了有关Google Analytics(分析)Google analytics inside shadow DOM doesn't work的未解决问题,对Adobe Analytics也是如此吗?
答案 0 :(得分:1)
首先,使用Shadow DOM概念的精神是为Web组件提供范围/封闭性,以便人们不能只是去戳它们并弄乱它们。原则上,这类似于在函数内部具有较高范围无法触及的局部范围变量。在实践中,可以绕过这个“墙”并按自己的方式行事,但它破坏了影子DOM的“精神”,这是IMO不好的做法。
因此,如果我要就这方面的一些最佳实践提出建议,我的第一条建议是尽可能多地尊重利用影子DOM的Web组件的精神,并将它们视为他们努力成为的黑盒。 。这意味着,您应该去负责Web组件的Web开发人员,并要求他们提供一个供您使用的界面。
例如,Adobe Launch能够侦听广播到(轻型)DOM的自定义事件,因此站点开发人员可以将其添加到其Web组件,创建自定义事件并单击按钮进行广播。
注意: Launch的自定义事件监听器将仅监听从document.body
开始的自定义事件广播,不 { {1}},因此请确保在document
或更深的地方创建和广播自定义事件。
“但是开发人员不会做任何事情,因此我必须自己处理问题……”
可悲的是,这经常是现实,因此您必须执行自己的操作。如果是这样的话,那么,Launch当前没有任何本机功能可以使您在此方面的生活变得更加轻松(无论如何,对于以下内容的“核心”部分而言),并且截至本文为止,AFAIK已有也没有提供任何扩展功能的公共扩展。但这并不意味着您就是SoL。
但是我想指出的是,我不确定我会很快将这个答案的其余部分称为“最佳实践”,就像“这是'a'解决方案..”一样。主要是因为这主要涉及将大量纯JavaScript倒入自定义代码框中并每天调用它,而这更像是“万能的,万不得已的解决方案”。
同时,通常最好的做法是,除非必须这样做,否则避免在标签管理器中使用自定义代码框。标签管理器的全部目的是抽象出代码。
我认为这里的TL; DR基本上是我重申的这一点,理想情况下,应将其放置在站点开发人员的职责范围内。但是,如果由于Reasons TM 而仍然真的需要在Launch中完成所有操作,请继续阅读。
注意: 这是一个简单的开放式影子DOM场景的非常基本的示例-实际上,您的场景几乎肯定要复杂得多。如果您要深入研究此问题,我希望您知道您在用JavaScript做些什么!
假设您在页面上有以下内容。自定义html元素的简单示例,其中的按钮已添加到其影子DOM。
document.body
假设您要在访问者单击按钮时触发规则。
快速解决方案示例
在这一点上,我可能应该说,您可以通过使用带有自定义代码条件的查询选择器<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
在这种情况下,类似的事情应该适用,因为这里有很多星星排列:
在实践中,您的要求可能不会那么容易。也许您需要附加一些其他事件侦听器,例如视频播放事件。不幸的是,目前还没有“一刀切”的解决方案。这取决于您的实际跟踪要求。
但是,总的来说,目标与您要求开发人员执行的目标几乎相同:在影子DOM的上下文中创建并广播自定义(轻型)DOM事件。
更好的解决方案示例
使用与上述相同的组件示例和要求,您可以例如创建一个规则以在DOM Ready上触发。将其命名为“我的组件跟踪-核心”之类的名称。没有条件,除非您想做类似检查Web组件的根灯DOM元素是否存在的操作。
总体而言,这是将事件侦听器附加到按钮并调度自定义事件以供Launch侦听的核心代码。请注意,此代码基于上面的示例组件和跟踪要求。此例是唯一的。您将需要根据自己的设置编写类似的代码。
添加带有以下内容的自定义js容器:
return event.nativeEvent.path[0].matches('button#myButton');
从这里,您可以创建一个新规则来监听自定义事件广播。
自定义事件规则示例
Rule name: My Button clicks
事件
Extension: Core Event Type: Custom Event Name: MyButtonClick Custom Event Type: MyButtonClick Elements matching the CSS selector: body
条件
*None for this scenario*
从这里,您可以设置所需的任何操作(设置Adobe Analytics变量,发送信标等)。
注意:
在此示例中,我向自定义事件发送了数据有效负载。您可以使用// 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);
}
}
在任何自定义(javascript)代码框中引用有效负载,例如event.detail
。您也可以使用event.detail.value
语法在“启动”字段中引用它们,例如%
。