我定义了自己的自定义元素,并发现将其子元素添加到阴影dom中很方便,主要是因为我可以在自定义元素构造函数中使用它,而同样的构造函数不允许我添加“常规”子元素。
自定义元素的构造函数不允许您添加子元素,因为新元素在创建后应该是空的。
我想知道是否有一种简单的方法可以在文档中使用css和样式来影响阴影dom中的元素。我希望light dom中的选择器能够在阴影dom中到达这些元素。
我的一个自定义元素是“项目”。我会创建很多来填充列表。我不喜欢在每个项目的实例'shadow dom中重复相同样式标记的想法,所以我正在寻找一个地方为我的所有项目添加此样式标记。
我读了很多关于影子dom的文章以及内部样式如何不影响边界之外的元素,但是他们中的任何一个都回答了我的问题。
有什么想法吗?谢谢!
shadow DOM的当前版本要求您将CSS放在shadow DOM中。
大多数CSS相当小,只在每个元素中添加几个字节到几百个字节。我看到一些最大的CSS在每个副本中添加了大约2k的CSS。但与DOM结构中表示的数据相比,这仍然非常小。
有一些东西会从外部流出,比如字体信息,但不是很多。
以下是一些可以从外部影响的方法:
CSS Variable允许您将变量设置为CSS中使用的值,无论是否在shadowDOM中。
可以捕获属性并将其迁移到shadowDOM CSS中。我有一些组件使用属性来定义主题。
也可以采用属性并将其应用于内部CSS。
讨论还有其他方法,但这些方法必须等到V2。
class MyEL extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'}).innerHTML = `
<style>
.outer {
color: var(--myColor, 'black');
</style>
<div class="outer">
<h4>Title</h4>
<slot></slot>
</div>`;
}
static get observedAttributes() {
return ['bgcolor'];
}
attributeChangedCallback(attrName, oldVal, newVal) {
if (oldVal !== newVal) {
this.shadowRoot.querySelector('.outer').style.backgroundColor = newVal;
}
}
get border() {
return this.shadowRoot.querySelector('.outer').style.border;
}
set border(value) {
this.shadowRoot.querySelector('.outer').style.border = value;
}
}
customElements.define('my-el', MyEL);
setTimeout(() => {
document.querySelector('my-el').border = '2px dashed blue';
},1000);
const btn = document.getElementById('toggle');
let color = '';
btn.addEventListener('click', () => {
color = color === '' ? 'white' : '';
document.querySelector('my-el').style.setProperty('--myColor', color);
});
<my-el bgcolor="red"></my-el>
<hr/>
<button id="toggle">toggle</button>