Search code examples
javascriptweb-componentshadow-dom

how to obtain ref to shadowRoot which contains given element


I am using web components.

I have a node tree like this, as described by the chrome dev tools inspector:

<div>
-- <my-fancy-custom-elem> (this is the web component)
---- #shadow-root
------ <div class="button-container">
-------- <button class="a-button-in-a-web-comp">

I am able to obtain a reference to the <button> through an event listener initiated outside of the web component's class.

Similar to this:

document.addEventListener("click", (event) => {
   const clickedElem = event.composedPath()[0]
   if(clickedElem.matches('.a-button-in-a-web-comp')){
     console.log(clickedElem.parentNode.parentNode)
   }
});

I can get a reference to the #shadow-root by calling clickedElem.parentNode.parentNode. However I am looking for a means to reliably get the shadow-root ancestor of that <button> no matter how deep in the tree it lives. And even if I don't know how deep in the tree it lives.

In other words I am looking for a way to reliably return the first shadow-root that contains X element, when I have a reference to X.


Solution

  • You can call clickedElem.getRootNode() to get the shadowRoot , as shown in the snippet below:

    class CustomButton extends HTMLElement{
      constructor(){
        super();
        this.attachShadow({"mode": "open"});
        this.shadowRoot.innerHTML = `
          <div>
            <button class="a-button-in-a-web-comp">Button</button>
           </div>
        `;
      }
    }
    customElements.define('custom-button', CustomButton);
    
    document.addEventListener("click", (event) => {
       const clickedElem = event.composedPath()[0];
       if(clickedElem.matches('.a-button-in-a-web-comp')){
         console.log(clickedElem.getRootNode())
       }
    })
    <custom-button></custom-button>