分析脚本未从影子DOM发送数据

时间:2019-03-13 10:30:12

标签: dom adobe shadow adobe-analytics

我们正在跟踪一个具有使用Shadow DOM概念构建组件的网站,当我们在启动时创建规则以向这些组件添加标记时,该站点将无法正常运行。

您可以为我们提供有关Shadow DOM中标记组件的最佳实践吗?

我发现了有关Google Analytics(分析)Google analytics inside shadow DOM doesn't work的未解决问题,对Adobe Analytics也是如此吗?

1 个答案:

答案 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中完成所有操作,请继续阅读。

“ A”解决方案...

注意: 这是一个简单的开放式影子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

在这种情况下,类似的事情应该适用,因为这里有很多星星排列:

  • shadow dom是开放模式,因此没有黑客可以覆盖事物
  • 对于光和阴影DOM级别都有容易识别的唯一CSS选择器
  • 您只想听点击事件,它会冒泡并 就像在阴影根的浅色DOM根上单击一样。

在实践中,您的要求可能不会那么容易。也许您需要附加一些其他事件侦听器,例如视频播放事件。不幸的是,目前还没有“一刀切”的解决方案。这取决于您的实际跟踪要求。

但是,总的来说,目标与您要求开发人员执行的目标几乎相同:在影子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语法在“启动”字段中引用它们,例如%