问题描述
TLDR::一旦我使用 Shadow DOM {em> Light DOM {1}}一个自定义元素在同一元素中声明的em>从浏览器视口中消失。
我正在学习/实验define()
和Custom Elements
。
我注意到,如果我有以下Shadow DOM
没有任何Custom Element
,它会起作用:
Shadow DOM
但是如果我然后,则通过<my-company>© 2020,</my-company>
向Custom Element
添加自定义内容...
原始的硬编码内容消失了。 (即使它在DOM Inspector中仍然仍然可见。)
我期望:
<my-company>© 2020,</my-company>
这是怎么回事?
这是否意味着不可能拥有
而我只能 可以选择以下任何一种方式:
- 没有
Shadow DOM
的{{1}} - 具有
Custom Element
和Shadow DOM
的{{1}}
或者有可能有Custom Element
和而没有Shadow DOM
?
解决方法
这是您的用例的简单解决方案,不需要slot
:
class myCompany_Element extends HTMLElement {
constructor() {
super()
this.root = this.attachShadow({ mode: 'open' })
}
connectedCallback() {
// added line below
this.root.textContent += this.textContent
this.root.textContent += 'Cyberdyne Systems'
}
}
customElements.define('my-company',myCompany_Element)
<my-company>© 2020,</my-company>
如果需要,也可以在设置this.textContent
之后将''
设为this.root.textContent
。据我所知,使用Chrome开发工具时,这样做对可访问性没有影响,但从开发人员的经验角度来看可能是可取的。
据我从实验和进一步阅读中得知,这是正在发生的事情:
通过调用attachShadow()
定义中的class
,我们明确确定元素将在Shadow Host
-d中变为define()
:
constructor() {
super();
this.root = this.attachShadow({mode: "open"});
}
元素正式成为Shadow Host
后,其 Light DOM 将不再显示在视口中:
-
Shadow Host
将不会显示HTML中已声明的 Light DOM -
Shadow Host
将不会显示以后通过Javascript添加的 Light DOM
进一步确认:
默认情况下,如果元素具有阴影DOM,则会渲染阴影树 代替元素的子元素
来源: https://polymer-library.polymer-project.org/3.0/docs/devguide/shadow-dom
结论:
带回元素的 Light DOM 子级的标准方法(也是唯一的方法)是使用名为<slot>
-s,在这种情况下:
class myCompany_Element extends HTMLElement {
constructor() {
super();
this.root = this.attachShadow({mode: "open"});
}
connectedCallback() {
this.root.innerHTML += '<slot name="template"></slot>';
this.root.innerHTML += 'Cyberdyne Systems';
}
}
customElements.define('my-company',myCompany_Element);
<my-company><span slot="template">© 2020,</span></my-company>