是否可以将事件侦听器绑定到来自外部脚本的影子 dom 内的元素?

Posted

技术标签:

【中文标题】是否可以将事件侦听器绑定到来自外部脚本的影子 dom 内的元素?【英文标题】:Is it possible to bind an event listener to an element within a shadow dom from external script? 【发布时间】:2016-03-10 18:54:22 【问题描述】:

我有一个 chrome 扩展,可以将 shadow dom 元素注入页面以保持 css 分离。但是我需要通过内容脚本将 onclick 绑定到 shadow dom 中的某些元素,因为我需要能够通过单击 shadow dom 中的元素来调用内容脚本中的函数。

我尝试在模板元素和实际的影子 dom 元素上使用 .bind('click', function()) 但我似乎无法访问它们。这可能吗?

【问题讨论】:

【参考方案1】:

尝试查询元素的 shadowRoot。换句话说,假设您有一个元素<super-ultra-element>,并且在该元素的shadow dom 内是一个带有“potato”类的div,您希望将点击处理程序附加到该div。

您应该可以通过首先获取元素的 shadowRoot 来做到这一点:var superUltraRoot = document.querySelector('super-ultra-element').shadowRoot;

一旦你有了shadowRoot,你就可以查询你关心的元素的shadow dom:var potatoDiv = superUltraRoot.querySelector('.potato');

您现在有一个对您尝试添加点击处理程序的元素的引用,因此这样做应该相当容易:potatoDiv.addEventListener('click', someClickCallback);

【讨论】:

虽然我不得不使用 querySelectorAll,但这绝对是答案。【参考方案2】:

我尝试在两个 模板元素中的元素

    向模板添加事件侦听器不起作用。您要绑定的元素应该是 DOM 的一部分。

还有实际的 shadow dom 元素,但我似乎无法访问它们

    我认为 jquery 还不了解 shadow-root。如果您使用 jquery 查询 shadow-dom 中的元素,我认为它不会返回节点(应该吗?)

所以,你有两个选择:

    正如其他答案中所建议的那样,您可以通过在 shadow-root 中查询事件监听器来将其绑定到实际元素,这可以通过元素上的 shadowRoot 属性访问。 或者,您可以使用适当的选择器使用jQuery event-delegation绑定父级(在本例中 host shadow-dom)。当事件将传播到父级时,将触发侦听器。

例如:

$( "#list" ).on( "click", "a", function( event ) 
    event.preventDefault();
    console.log( $( this ).text() );
);

【讨论】:

以上是关于是否可以将事件侦听器绑定到来自外部脚本的影子 dom 内的元素?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以将 socket.io 限制为每个事件只有一个侦听器?

将事件绑定到动态创建的 iframe 元素

数据绑定:将来自侦听器的单个方法与多个方法绑定

AppleScript 可以监听事件吗?

为啥我的动作脚本事件没有触发?

将 Google 地图标记绑定到非地图侧边栏条目