Search code examples
javascripthtmlpolymerweb-componentshadow-dom

Plain Javascript code that does what querySelector() and querySelectorAll() does, include shadowroots


I am trying to write a method that takes in two params: one of the parentNode of the current element where many childNodes with shadowroots within it, the second param being the id of an element within one of the shadowroots of one of the childNodes of this parentNode param. I tried to use the generic querySelector() methods that JS come with to find the element using the id alone, but it wouldn't work due to my element tags being inside the shadowroot. Due to this reason, I had write code that are more or less hard-coded that traverse through the DOM tree by their tag name, hence the idea of writing a more dynamic method that handles the matching. Here is an html sample of what I am dealing with, using a bunch of customized web components tags (Hence why the shadowroots):

<body>
<my-app>
    <main id="main">
        <my-app-pub>
            <section>
                <my-app-workpackage id="wp">
                    <my-table id="mytable1" data={...}>
                        #shadow-root (open)
                            <style></style>
                            <table>
                                <thead></thead>
                                <tbody>
                                    <tr id="tr1"></tr>
                                    <tr id="tr2"></tr>
                                    <tr id="tr3"></tr>
                                </tbody>
                            </table>
                    </my-table>

                    <my-table id="mytable2" data={...}>
                        #shadow-root (open)
                            <style></style>
                            <table>
                                <thead></thead>
                                <tbody>
                                    <tr id="tr4"></tr>
                                    <tr id="tr5"></tr>
                                    <tr id="tr6"></tr>
                                </tbody>
                            </table>
                    </my-table>
                </my-app-workpackage>
            </section>
        </my-app-pub>
    </main>
</my-app>

Giving that I have a variable with the parent element <my-app-workpackage>, and the id of the element I want to find as tr2, how should I write a method to handle that?


Solution

  • You must create a parser that will check recursively the DOM :

    For each node :

    1. If there's a Shadow DOM (shadowRoot not null), parse the Shadow tree.
    2. Or else parse the children DOM tree.

    If you use <slot> you'll have look for distributed nodes too, but it's not asked in your question...