我可以 select 存在于 Shadow DOM 中的聚合物元素吗?

Can I select Polymer elements that exist in the Shadow DOM?

我有一个用 Polymer 制作的应用程序需要自动化。问题是它有很多 Shadow DOM。

我使用的 FluentAutomation 只知道使用 CSS 选择器和一些 jQuery.

有没有办法使用 CSS 选择器识别 Shadow DOM 中的元素?

你是说 select 一个 dom 节点是影子 dom 的一部分吗?

因为我没有 select 或刺穿阴影 dom 你必须提供 dom 节点的完整路径。 示例来源:

<my-app>
  #shadow-root
    <h3 part="header">My App Header</h3>
    <my-dialog>
      #shadow-root
        <p part="header">My Dialog Header</p>
        <my-alert>
          #shadow-root
            <span part="header">My Alert Header</span>
        </my-alert>
        <my-alert>
          #shadow-root
            <span part="header">My Alert Header</span>
        </my-alert>
    </my-dialog>
</my-app>

要select第一个my-alert你需要做

document.querySelector('my-app').shadowRoot.querySelector('my-dialog').shadowRoot.querySelector('my-alert');

如果你有这样的ID

<my-app id="app">
  #shadow-root
    <h3 part="header">My App Header</h3>
    <my-dialog id="dialog">
      #shadow-root
        <p part="header">My Dialog Header</p>
        <my-alert id="alert1">
          #shadow-root
            <span part="header">My Alert Header</span>
        </my-alert>
        <my-alert id="alert2">
          #shadow-root
            <span part="header">My Alert Header</span>
        </my-alert>
    </my-dialog>
</my-app>

您可以使用更优化的路径。

document.querySelector('my-app').$.dialog.$.alert1

PS:如果您有兴趣,作品中有一个 selector 可以让您刺穿某些“导出”dom 部分的阴影 dom……
规格:https://tabatkins.github.io/specs/css-shadow-parts/
博客 Post:https://meowni.ca/posts/part-theme-explainer/

我最终使用了一位同事提供的脚本来搜索阴影圆顶中的元素:

    (() => {
            if (window.DeepShadowDom !== undefined) {
                return;
            }

            const findAll = (selector, root = document) => {
                let elements = [ ];

                Array.prototype.push.apply(elements, root.querySelectorAll(selector));

                Array.prototype.slice.call(root.querySelectorAll('*'))
                    .filter(e => e.shadowRoot !== null)
                    .forEach((currentElement, index, array) => {

                        let candidates = findAll(selector, currentElement.shadowRoot);

                        Array.prototype.push.apply(elements, candidates);
                    });

                return elements;
            };

            const find = (selector, root = document) => {
                let elements = findAll(selector, document);

                if (elements.length > 1) {
                    throw new Error(`Multiple results returned by selector '${selector}'`);
                }

                return elements[0];
            };

            window.DeepShadowDom = { find, findAll };
        })();

然后可以通过选择 DeepshadowDom.Find(选择器)

找到该元素