【问题标题】:Can I select Polymer elements that exist in the Shadow DOM?我可以选择 Shadow DOM 中存在的 Polymer 元素吗?
【发布时间】:2018-08-14 00:51:30
【问题描述】:

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

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

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

【问题讨论】:

  • "很多 Shadow DOM" 只有一个 Shadow DOM。你能澄清一下你的意思吗?
  • 我不熟悉 Polymer / shadow DOM。在 DOM 中导航到我想要的元素时,我只看到了多个。

标签: css-selectors polymer-2.x shadow-dom fluentautomation


【解决方案1】:

您的意思是选择一个属于影子 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>

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

【讨论】:

  • 感谢您的回答,我最终像您提供的解决方案一样执行了 javascript。
  • 我剩下的问题是我无法通过 CSS 路径或使用 jquery 来识别元素,例如 E:contains('t') ,因为那个阴影圆顶。这限制了我在 FluentAutomation 框架中的操作,该框架具有 Click、Hover、Type、Find 等操作,将 CSS 选择器作为参数...
  • 你能提供一个元素而不是css选择器吗? (也许一些额外的选项?)如果不是,为该选项发出合并请求可能仍然更容易......然后创建一个可以使用特殊“标记”来遍历影子doms的jquery插件......(如果那是甚至很容易?)
  • 我的开发同事帮助我创建了一个搜索所有阴影圆顶并返回元素的脚本:
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2019-02-27
    • 1970-01-01
    • 2014-10-02
    • 2014-09-27
    • 1970-01-01
    • 1970-01-01
    • 2017-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多