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

问题描述 投票:0回答:3

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

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

javascript google-chrome dom content-script shadow-dom
3个回答
25
投票

尝试查询元素的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);


0
投票

我尝试在两个上使用 .bind('click', function(){}) 模板元素中的元素

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

以及实际的 Shadow dom 元素,但我似乎无法访问它们

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

所以,你有2个选择:

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

例如:

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

0
投票

我正在使用 Jquery

find
on
函数的替代方法,请在此处尝试我的代码片段。

$("#CreateShadowRoot").on('click', function (event) {
    const shadowDiv = document.getElementById('ShadowDiv');
    const shadowRoot = shadowDiv.attachShadow({ mode: 'open' });
    const jQueryScript = document.createElement('script');
    jQueryScript.src = 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js'; 
    shadowRoot.appendChild(jQueryScript);
    shadowRoot.innerHTML += '<button id="example-action">Im inside ShadowRoot</button>';
    function initShadowDOM() {
      // Get the Shadow DOM root element
      // Attach a click event listener using jQuery
      $(shadowRoot).find("#example-action").on('click', function (event) {
        // Handle the click event within the Shadow DOM
        // You can access the event object and perform actions here
        console.log('Event received');
      });
    }
    jQueryScript.onload = function () {
      // jQuery is now loaded and ready to use
      // You can use jQuery event listeners like .on() here
      initShadowDOM(); // Call a function to set up the Shadow DOM content and event listeners
    };
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="CreateShadowRoot">Create ShadowRoot</button>
<div id="ShadowDiv"></div>

© www.soinside.com 2019 - 2024. All rights reserved.