执行 querySelector() 和 querySelectorAll() 功能的普通 Javascript 代码,包括 shadowroots

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

我正在尝试编写一个接受两个参数的方法:一个是当前元素的 parentNode,其中有许多子节点,其中包含 shadowroots,第二个参数是一个元素的 shadowroots 中的一个元素的 id此 parentNode 参数的 childNodes。我尝试使用 JS 附带的通用 querySelector() 方法来单独使用 id 来查找元素,但由于我的元素标签位于 shadowroot 中,所以它不起作用。由于这个原因,我编写了或多或少硬编码的代码,这些代码通过标签名称遍历 DOM 树,因此我想到了编写一个更动态的方法来处理匹配。这是我正在处理的 html 示例,使用了一堆自定义的 Web 组件标签(因此为什么使用 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>

假设我有一个父元素 <my-app-workpackage> 的变量,我想找到的元素的 id 为 tr2,我应该如何编写一个方法来处理它?

您必须创建一个解析器来递归检查 DOM :

对于每个节点:

  1. 如果有 Shadow DOM(shadowRoot 不是 null),解析 Shadow 树。
  2. 否则解析子 DOM 树。

如果您使用 <slot>,您也会寻找分布式节点,但您的问题中没有询问...