完整详解在:::slotted CSS selector for nested children in shadowDOM slot
<foo-bar>
<h1>Test</h1>
</foo-bar>
H1 是 lightDOM,
“添加” 到 shadowDOM/ root 内容反映到 shadowDOM,没有移动!!!
H1 始终保留在 lightDOM 中:
你说:所以它们在 dom 中,但没有渲染,即使你的 CSS 告诉相反?
不,它们是渲染的,就像任何普通的 DOM 元素一样。只是不再可见。
您可以通过在 lightDOM 中包含一个 SCRIPT 标签进行测试。它会渲染并执行!
在下面的代码sn-ps中
你用this.querySelector("span").innerHTML="weird";引用lightDOM
但是用this.shadowRoot.querySelector("span").innerHTML="weird";引用shadowDOM
不工作,因为 DIV(内部有 SPAN)在
中是
黑盒
<template id="MY-ELEMENT">
<style>
:host {
display: inline-block;
font-family: Arial;
}
::slotted(div){
color:blue;
}
::slotted(span){
color:gold; /* alas, you can style the 'box', not elements inside */
}
</style>
<h3><slot></slot></h3>
</template>
<style>
span {
background:lightcoral; /* from global/host CSS, style slotted content lightDOM */
}
</style>
<script>
customElements.define('my-element', class extends HTMLElement {
constructor() {
super().attachShadow({mode: 'open'})
.append(document.getElementById(this.nodeName).content.cloneNode(true));
}
});
</script>
<my-element>
<div>Hello <span>Component</span> World!</div>
</my-element>
在 F12 开发工具中检查组件:
Chrome 和 Firefox:
DIV 不在 shadowDOM/root 中,在 lightDOM 中保持不可见
所有元素/样式将始终反映到 shadowDOM/root
点击“显示”将带您进入 lightDOM
所以对 shadowDOM,开槽内容是元素和样式的黑盒;
反映来自 lightDOM
这就是为什么::slotted 只能设置盒子的样式,而不能设置里面的样式。
注意:在 F12 控制台中编辑该 DIV,您会立即看到更改反映到 shadowDOM
SLOT 和 lightDOM 是实时连接
通过更改<slot name=...>,您可以进行以前需要更多编码的交互(想想路由、选项卡、答案)(还记得那些 jQuery 显示/隐藏的日子吗?)
<template id="MY-ELEMENT">
Custom Element SLOTs are:
<slot name=answer></slot>
</template>
<style>
img { /* style all IMGs in lightDOM */
max-width: 100vw;
max-height: 70vh;
}
</style>
<script>
customElements.define('my-element', class extends HTMLElement {
connectedCallback() {
this.attachShadow({mode: 'open'})
.append(document.getElementById(this.nodeName).content.cloneNode(true));
this.onclick = (evt) => {
const answer = evt.composedPath()[0].innerText; // button label
this.shadowRoot.querySelector('slot').name = answer;
this.children[0].slot = answer;//include lightDOM buttons again
}
}
});
</script>
<my-element>
<span slot=answer><button>Cool</button><button><b>Awesome</b></button><button>Great</button></span>
<div slot=Cool><img src="https://i.imgur.com/VUOujQT.jpg"></div>
<span slot=Awesome> <h3>SUPER!</h3></span>
<div slot=Awesome><img src="https://i.imgur.com/y95Jq5x.jpg"></div>
<div slot=Great><img src="https://i.imgur.com/gUFZNQH.jpg"></div>
</my-element>
更多 SLOT 相关答案可以通过 StackOverflow 搜索找到:Custom Elements SLOTs