Polymer 使用document.getElementById将web组件元素从ShadowDom公开给外部JS

Polymer 使用document.getElementById将web组件元素从ShadowDom公开给外部JS,polymer,web-component,shadow-dom,pwa-starter-kit,Polymer,Web Component,Shadow Dom,Pwa Starter Kit,我正在使用Polymer当前的PWA初学者工具包模板 My web component元素页返回以下带有DIV元素的代码: return html` ${SharedStyles} <section> ...my content... </section> <div id="CONTAINER NAME"></div> ` 返回html` ${SharedStyl

我正在使用Polymer当前的PWA初学者工具包模板

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

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

      </section>
      <div id="CONTAINER NAME"></div>
    `
返回html`
${SharedStyles}
…我的内容。。。
`
我需要通过document.getElementById从外部javascript访问CONTAINER NAME元素。我知道它位于阴影dom中,但我无法更改外部JS。所以问题是如何通过document.getElementById从JS访问它

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

我已经搜索过了,但还没有找到一种方法来强制我的web组件页面的shadowdom中的div元素暴露/放置在dom中

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

有什么方法可以更新基于Polymer v3/PWA工具包的web组件,而外部javascript(第三方)仍然使用document.getElementbyId修改web组件内部的div


那么,是否正在寻找一种可能,使用slot将阴影dom的一个元素暴露给light dom?但是它无法与上面链接的解决方案一起使用。

正如您所提到的,lit元素默认使用shadow dom,因为它在制作可重用组件时有很多优点

但是,您可以选择退出它并使用“light”dom,它将在主dom中呈现组件的内容,而主dom将使用
document.getElementById()
document.querySelector()

下面是一个如何在基于lit元素的组件中使用light dom的最小示例(这里是一个您可以看到它的实际应用的示例)

MyElement类扩展了LitElement{
render(){
返回html`
…我的内容。。。
这是我元素中的一个容器
`;
}
createRenderRoot(){
//这就是覆盖lit元素行为的原因,这样内容就不会在阴影dom中呈现
归还这个;
}
}
请记住,在这种情况下,您应该只在应用程序中使用此组件一次,因为
getElementById()
是如何工作的,并且您将无法在组件中使用
,因为这是仅适用于阴影dom的功能

那么,是否有可能使用插槽将阴影dom的一个元素暴露给灯光dom?但是不能让它与上面链接的解决方案一起工作

实际上,您应该做的是相反的:公开要在light DOM中选择的
,并在需要时通过
标记将其集成到Shadow DOM中

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

      </section>
      <slot></slot>
    `
this.innerHTML=''
返回html`
${SharedStyles}
…我的内容。。。
`

此解决方案有效。但是,我必须将
createRenderRoot
也放在组件的父级中。在那之后它就开始工作了。但是,我现在已经破坏了父组件中的样式模板,因为样式变量不再填充到子元素中。必须与父级上的createRenderRoot相关?是的,我想我在某个地方读到过,使用light dom基本上意味着你必须使用“普通”css进行样式设置,在这种情况下,你可以将这些样式作为全局样式添加到你的html中。我想我只是更新了这个小故障,以展示你如何处理这种情况下的样式设置。就是这样!只需将样式变量放入普通html就解决了样式主题。非常感谢。这个解决方案也起了作用。但我还必须将createRenderRoot()添加到元素中才能使其正常工作。
this.innerHTML = '<div id="CONTAINER NAME"></div>'
return html`
      ${SharedStyles}    
      <section>
        ...my content...

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