1

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

我正在使用 FluentAutomation,它只知道使用 CSS 选择器和一些 jQuery。

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

4

2 回答 2

2

你的意思是选择一个属于影子dom的dom节点吗?

因为我没有穿透阴影 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>

要选择第一个我的警报,您需要做

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

如果你有这样的身份证

<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:如果您有兴趣,作品中有一个选择器可以让您为某些“导出”的 dom 部分刺穿 shadow dom……<br> 规范:https ://tabatkins.github.io/specs/css-shadow-parts /
博客文章:https ://meowni.ca/posts/part-theme-explainer/

于 2018-03-07T14:08:32.343 回答
1

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

    (() => {
            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(selector) 找到该元素

于 2018-11-20T10:22:21.570 回答