1 回答
TA贡献1943条经验 获得超7个赞
<SLOTs>
无法像“普通”DOM 元素一样定位
(和许多人一样)您陷入了认为分槽内容
已移动到 ShadowDOM 的陷阱<slots>
它不是。
开槽内容仅在 ShadowDOM 中反射,它仍然不可见!在 lightDOM 中
您无法使用或...访问反射内容 ,因为它不在那里(在 ShadowDOM 中).. 它仍然在 lightDOM 中。.querySelector
.children[]
出于同样的原因,您可以在 lightDOM 中设置开槽内容的样式:
使用 CSS 选择器,例如 :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 是最简单的,因为它不需要任何<slots>
ShadowDOM
slotchange
2. 对于在shadowDOM 模板中
需要(命名/未命名)的事件,您的思路是正确的。 您可以在以下位置找到 lightDOM 节点:<slot></slot>
MDN:分配的节点
MDN:分配元素
请注意,这会获取所有节点类型,包括text
节点,因为innerHTML 中存在换行符和空格<my-element>
!
<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/
- 1 回答
- 0 关注
- 79 浏览
添加回答
举报