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

Is it possible to bind an event listener to an element within a shadow dom from external script?

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

我已经尝试在模板元素和实际阴影 dom 元素上使用 .bind('click', function(){}) 但我似乎做不到访问它们。这可能吗?

尝试查询元素的 shadowRoot。换句话说,假设您有一个元素 <super-ultra-element>,并且在该元素的影子 dom 内是一个 div 和 class 'potato',您希望附加一个单击处理程序。

您应该能够通过首先获取元素的 shadowRoot 来执行此操作:var superUltraRoot = document.querySelector('super-ultra-element').shadowRoot;

获得 shadowRoot 后,您可以查询元素的影子 dom 以查找您关心的项目:var potatoDiv = superUltraRoot.querySelector('.potato');

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

I have tried using the .bind('click', function(){}) on both the elements in the template element

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

and the actual shadow dom element but I can't seem to access them

  1. 我认为 jquery 还没有理解 shadow-root。如果您使用 jquery 来查询 shadow-dom 中的元素,我认为它不会 return 一个节点(应该吗?)

所以,你有两个选择:

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

例如:

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