我试图将一个元素从 light DOM 移动到 Shadow DOM,但是当我这样做时,样式并没有复制过来。我尝试通过设置
newElement.style = window.getComputedStyle(elem)
来解决此问题,但这似乎不起作用。样式应该是:
.card {
color: #ff0;
font-size: 3rem;
font-weight: 600;
border: 3px solid blueviolet;
background-color: greenyellow;
}
但样式不适用,当我打印
getComputedStyle()
来控制台时,我看到的是:
所有值均为空
但是,当我像这样使用
getComputedStyle()
循环遍历 .getPropertyValue()
的属性时:
for(let property of style){
console.log(`property: ${property}, value: ${style.getPropertyValue(property)}`);
}
我在控制台中得到的是: 正确的数值
所以我很困惑为什么
getComputedStyle()
不包含这些值,但使用 getComputedStyle().getPropertyValue()
会返回正确的值。我确信我错过了一些明显的东西,因为我在任何地方都找不到关于此的其他帖子。
任何帮助将不胜感激,提前致谢。
编辑:我已采用下面丹尼提供的代码并对其进行修改以更好地显示我面临的问题:
<style>
.card {
color: yellow;
background: green;
}
</style>
<my-element>
<div class="card">lightDOM reflected to shadowDOM</div>
</my-element>
<script>
customElements.define("my-element", class extends HTMLElement {
constructor(){
super().attachShadow({mode:"open"}).innerHTML = ``;
}
connectedCallback() {
setTimeout(() => { // wait till innerHTML is parsed
let card = this.children[0]; // Get the light DOM Card element
this.shadowRoot.appendChild(card.cloneNode(true)); // Append it to the shadowDOM
let style = window.getComputedStyle(card); // Get style of the Light DOM Card
this.shadowRoot.querySelector('.card').style = style; // Set the ShadowDOM card style equal to the Light DOM Style
console.log(style);
console.log(style.color); // yellow = rgb:255,255,0
console.log(style.background); // green = rgb:0,128,0
card.remove(); // Remove the card from the Light DOM to prevent duplication
})
}
})
</script>
请注意,上面的样式并不适用,尽管它似乎与文档指定的完全相同: “返回的对象与从元素的 style 属性返回的对象是相同的 CSSStyleDeclaration 类型。但是,这两个对象有不同的用途:
来自 MDN 文档:
在应用活动样式表并解析这些值可能包含的任何基本计算之后,
方法返回一个包含元素的所有CSS属性值的对象。 各个 CSS 属性值可通过对象提供的 API 或通过 CSS 属性名称索引来访问。Window.getComputedStyle()
说明需要使用API函数,比如
getPropertyValue()
来获取它的值。
参考:https://developer.mozilla.org/en-US/docs/Web/API/Window/getCompulatedStyle
如果你想打印特定元素的所有 CSS 样式,你可以像这样迭代所有属性:
function dumpCSSText(element){
var s = '';
var o = getComputedStyle(element);
for(var i = 0; i < o.length; i++){
s+=o[i] + ': ' + o.getPropertyValue(o[i])+';\n';
}
return s;
}
var e = document.querySelector('.card');
console.log(dumpCSSText(e));
.card {
color: #ff0;
font-size: 3rem;
font-weight: 600;
border: 3px solid blueviolet;
background-color: greenyellow;
}
<div class="card"></div>
属性
style
是 只读,因此您无法为其分配任何内容;innerHTML
触发时,
自定义元素的connectedCallback
尚未解析。因此,使用
getComputedStyle
获取其子元素的样式是对不存在元素的操作。
如果您reflect lightDOM 内容到shadowDOM 中的
<slot>
,则无需复制样式,因为lightDOM 中的样式已reflected
<style>
.card {
color: yellow;
background: green;
}
</style>
<my-element>
<div class="card">lightDOM reflected to shadowDOM</div>
</my-element>
<script>
customElements.define("my-element", class extends HTMLElement {
constructor(){
super().attachShadow({mode:"open"}).innerHTML = `<slot></slot>`
}
connectedCallback() {
setTimeout(() => { // wait till innerHTML is parsed
let card = this.querySelector(".card"); // in lightDOM!
let style = window.getComputedStyle(card);
console.log(style.color); // yellow = rgb:255,255,0
console.log(style.background); // green = rgb:0,128,0
})
}
})
</script>