使用 document.getElementById 将 ShadowDom 中的 Web 组件元素公开给外部 JS

Expose web-component element from ShadowDom to external JS using document.getElementById

我正在使用 Polymer 的当前 PWA 入门工具包模板。

https://github.com/Polymer/pwa-starter-kit/tree/template-typescript

我的网络组件元素页面 return 以下代码带有 DIV 元素:

return html`
      ${SharedStyles}    
      <section>
        ...my content...

      </section>
      <div id="CONTAINER NAME"></div>
    `

我需要通过 document.getElementById 从外部 javascript 访问 CONTAINER NAME 元素。我知道它位于阴影中 dom 但我无法更改外部 JS。所以问题是如何通过 document.getElementById?

从 JS 访问它

外部 JavaScript 将 iframe 加载到命名的 div 中。此外部组件需要通过 document.getElementById 获取 div 元素以将 iframe 加载到指定的 div 中。

我已经搜索过,但没有找到一种方法来将我的网络组件页面的阴影 dom 中的 div 元素强制为 [=48] 中的 exposed/placed =].

我刚刚发现这里提到的这个解决方案,但我没有让它在 PWA 模板中工作。可能因为阴影 dom 级联在 PWA 模板中?

有什么方法可以更新基于 Polymer v3/PWA 套件的 Web 组件,外部 javascript(第三方)仍然使用 document.getElementbyId 修改我的 div 在 Web 组件中?

因此寻找可能使用 slots 将阴影 dom 的元素暴露在光线 dom 下的可能性?但是无法让它与上面链接的解决方案一起使用。

如您所述,lit-element 默认使用阴影 dom,因为它在您制作可重用组件时有很多优势。

但是,您可以选择退出它并使用 "light" dom,这将在主要 dom 中呈现组件的内容,这反过来又可以使用诸如此类的方式访问该内容document.getElementById()document.querySelector()

这是一个关于如何在基于光照元素的组件中使用光 dom 的最小示例(这里是 glitch 您可以在其中看到它的实际效果)

class MyElement extends LitElement {  
  render() {
    return html`
      <section>
        ... My content ...
      </section>
      <div id="myElementContainer">
        This is a container inside my element
      </div>
    `;
  }

  createRenderRoot() {
    // this is what overrides lit-element's behavior so that the contents don't render in shadow dom
    return this;
  }

}

请记住,在这种情况下,由于 getElementById() 的工作原理,您只能在您的应用程序中使用该组件一次,并且您将无法在您的组件中使用 <slot>因为这是仅适用于阴影的功能 dom

So looking for a possibility using maybe slots to expose an element of the shadow dom to the light dom? But cant get it to work with the solutions linked above.

实际上你应该做的恰恰相反:将要选择的 <div> 暴露在光线 DOM 中,然后通过 <slot> 将其集成到阴影 DOM 中如果需要,请标记。

this.innerHTML = '<div id="CONTAINER NAME"></div>'
return html`
      ${SharedStyles}    
      <section>
        ...my content...

      </section>
      <slot></slot>
    `