【问题标题】:How to select element inside open Shadow DOM from Document?如何从文档中选择打开的 Shadow DOM 中的元素?
【发布时间】:2020-01-08 19:24:02
【问题描述】:

假设我的文档中有一个如下所示的 DOM:

<body>
  <div id="outer">
    <custom-web-component>
      #shadow-root (open)
        <div id="inner">Select Me</div>
    </custom-web-component>
  </div>
</body>

是否可以在 document 上使用单个 querySelector 参数选择影子根内的内部 div?如果有,它是如何构建的?

例如,document.querySelector('custom-web-component &gt; #inner') 之类的东西

【问题讨论】:

    标签: html css shadow-dom


    【解决方案1】:

    你可以这样做:

    document.querySelector("custom-web-component").shadowRoot.querySelector("#inner")

    【讨论】:

      【解决方案2】:

      简而言之,不完全是。 TL:DR 是,根据组件的设置方式,您可能可以执行以下操作:

      document.querySelector('custom-web-component').div.innerHTML = 'Hello world!';
      

      执行此操作 - 如果您有权访问 Web 组件的创建位置,则可以在此处添加一个接口来访问内部内容。您可以像公开任何 JavaScript 类变量/方法一样执行此操作。比如:

      /**
       *  Example web component
       */
      class MyComponent extends HTMLElement {
        constructor() {
          super();
      
          // Create shadow DOM
          this._shadowRoot = this.attachShadow({mode: 'open'});
          
          // Create mock div - this will be directly accessible from outside the component
          this.div = document.createElement('div');
          
          // And this span will not
          let span = document.createElement('span');
          
          // Append div and span to shadowRoot
          this._shadowRoot.appendChild(span);
          this._shadowRoot.appendChild(this.div);
        }
      }
      
      // Register component
      window.customElements.define('custom-web-component', MyComponent);
      
      // You can now access the component 'div' from outside of a web component, like so:
      (function() {
        let component = document.querySelector('custom-web-component');
        
        // Edit div
        component.div.innerHTML = 'EDITED';
        
        // Edit span
        component._shadowRoot.querySelector('span').innerHTML = 'EDITED 2';
      })();
      &lt;custom-web-component&gt;&lt;/custom-web-component&gt;

      在这种情况下,您可以从组件外部访问div,但无法访问span

      补充:由于 Web 组件是封装的,我认为您不能以其他方式选择组件的内部部分 - 您必须使用this 明确设置选择它们的方式,如上所述。

      编辑:

      也就是说,如果您知道影子根密钥是什么,您可以这样做:component._shadowRoot.querySelector()添加到上面的演示中)。但这样做是一件很奇怪的事情,因为它有点违背封装的想法。

      编辑 2

      上述方法仅在使用this 关键字设置影子根时有效。如果影子根设置为let shadowRoot = this.attachShadow({mode: 'open'}),那么我认为您将无法搜索span - 不过那里可能是错误的。

      【讨论】:

      • 感谢您富有洞察力和详细的回答。不幸的是,我正在寻找并希望有一个单一的 querySelector 参数字符串,因为我目前绑定到一个需要它的 API :(
      • 真可惜。我想那么答案可能是否定的。如上所述,你能得到的最接近的是let innerDiv = document.querySelector('custom-web-component').div。我不知道任何其他方法。
      猜你喜欢
      • 2019-02-27
      • 1970-01-01
      • 2016-09-19
      • 2018-04-19
      • 1970-01-01
      • 1970-01-01
      • 2017-12-10
      • 1970-01-01
      • 2018-08-14
      相关资源
      最近更新 更多