我的评论太快了。
<SLOTs> 不能像“普通”DOM 元素一样定位
(像许多人一样)您正在陷入思考插槽内容的陷阱
已移动到 ShadowDOM <slots>
不是。
slotted 内容只是 REFLECTED 在 shadowDOM 中,它仍然在 lightDOM 中保持不可见!
您可以不通过.querySelector或.children[]访问反映内容
...因为它不存在(在 shadowDOM 中).. 它仍然在 lightDOM 中。
出于同样的原因,您在 lightDOM 中设置插槽内容的样式:
Use CSS selectors like :first-child inside shadow dom
将 lightDOM <OPTIONs> 附加到 shadowDOM <SELECT`>
1.您可以将它们从 lightDOM 移动到 shadowDOM:
let select = this.shadowRoot.querySelector('select');
let host = this.shadowRoot.getRootNode().host;
let options = host.querySelectorAll('option');
select.append(...options);
#1 是最简单的,因为它不需要 shadowDOM 中的任何 <slots>
2。您在 slotchange 事件中走在正确的轨道上
它需要 shadowDOM 模板中的(命名/未命名)<slot></slot>。
您可以在以下位置找到您的 lightDOM 节点:
请注意,这会得到所有nodeTypes 包括text 节点,因为<my-element> 内部HTML 中有换行符和空格!
<my-element>
<option>Grow up</option>
<option>Learn React</option>
<option>Learn Lit</option>
<option>Forget W3C standard Custom Elements API</option>
<H1 slot=title>My Never Todo List</hH>
</my-element>
幸运的是<SELECT> 不在乎,所以你可以直接转储assignedNodes..
this.shadowRoot.addEventListener('slotchange', (evt) => {
if (!evt.target.name) { // only for unnamed slot
this.shadowRoot.querySelector('select')
.append(...evt.target.assignedNodes());
}
});
注意!<options> 被反映到未命名的槽,
<H1 slot=title>反映到<slot name=title>
(他们应该将它们命名为 reflections 而不是 slots)
点击显示代码片段查看完整代码
customElements.define("my-element", class extends HTMLElement {
connectedCallback() {
let template = document.getElementById(this.nodeName);
this.attachShadow({
mode: 'open'
}).append(template.content.cloneNode(true));
this.shadowRoot.addEventListener('slotchange', (evt) => {
if (!evt.target.name) { // only for unnamed slot
let select = this.shadowRoot.querySelector('select');
select.append(...evt.target.assignedNodes());
}
});
}
})
<template id=MY-ELEMENT>
<style>
:host {
display: block;
}
select{
font-size:1.5em;
}
</style>
<slot name=title></slot>
<select multiple>
</select>
<slot></slot>
</template>
<my-element>
<option>Grow up</option>
<option>Learn React</option>
<option>Learn Lit</option>
<option>Forget W3C standard Custom Elements API</option>
<h1 slot=title>My Never Todo List</h1>
</my-element>
具有两个选项的 JSFiddle 游乐场:
https://jsfiddle.net/CustomElementsExamples/v2f9zmu5/
更多 SLOT 相关答案可以通过 StackOverflow 搜索找到:Custom Elements SLOTs