【问题标题】:Expose web-component element from ShadowDom to external JS using document.getElementById使用 document.getElementById 将 Web 组件元素从 ShadowDom 公开给外部 JS
【发布时间】:2018-11-07 14:06:21
【问题描述】:

我正在使用 Polymer 当前的 PWA 入门套件模板。

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

我的 web-component 元素页面返回以下带有 DIV 元素的代码:

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

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

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

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

我已经搜索并没有找到一种方法来强制将我的 web 组件页面的 shadow dom 中的 div 元素暴露/放置在 DOM 中。

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

https://stackoverflow.com/a/47082470/9192527

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

所以寻找一种可能使用slots 将shadow dom 的元素暴露给light dom 的可能性?但不能让它与上面链接的解决方案一起工作。

【问题讨论】:

    标签: polymer web-component shadow-dom pwa-starter-kit


    【解决方案1】:

    正如您所提到的,lit-element 默认使用 shadow dom,因为它在您制作可重用组件时具有很多优势。

    但是,您可以选择不使用它并使用“轻”dom,它将在主 dom 中呈现组件的内容,这反过来又可以使用 document.getElementById()document.querySelector() 等方式访问该内容

    这是一个关于如何在基于 lit-element 的组件中使用 light 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() 是如何工作的,并且您将无法在组件中使用 &lt;slot&gt;,因为这是一项仅可用的功能阴影域

    【讨论】:

    • 此解决方案有效。但是,我必须将createRenderRoot 也放在组件的父级中。之后它就起作用了。但是,我现在已经从父组件中破坏了我的样式模板,因为样式变量不再填充到子元素中。必须与父级上的 createRenderRoot 相关吗? ?
    • 是的,我想我在某处读到过,使用 light dom 基本上意味着你必须使用“普通”css 来设置样式,对于这种情况,我猜你可以将这些样式添加为 html 中的全局样式跨度>
    • 我刚刚更新了故障以展示如何处理这种情况下的样式
    • 做到了!只需将样式变量放入普通 html 即可解决样式问题。谢谢!
    【解决方案2】:

    所以寻找一种可能性,使用槽将阴影 dom 的元素暴露给 light dom?但不能让它与上面链接的解决方案一起工作。

    实际上你应该做的是相反的:暴露&lt;div&gt;在light DOM中被选中,如果你需要,通过&lt;slot&gt;标签将它集成到Shadow DOM中。

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

    【讨论】:

    • 这个解决方案也有效。但我还必须将 createRenderRoot() 添加到元素中才能使其正常工作。
    猜你喜欢
    • 2018-04-14
    • 2017-06-22
    • 2018-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多