假设我在 HTML 文件中有一个按钮,
<button id="btn">Click Me</button>
使用 JavaScript 将该按钮的颜色更改为红色。
const btn = document.querySelector('#btn');
btn.style['background-color'] = 'red';
然后我检查了
btn.style['background-color']
。显示red
。
btn.addEventListener('click', () => {
console.log(`This button is in ${btn.style['background-color']}`)
});
所以我期望我的
btn.style
对象应该看起来像这样,
{
... ,
"background-color": "red",
...
}
但是当我在控制台打印它们时,为什么键值对是
0: "background-color"
,值在哪里red
?
btn.addEventListener('click', () => console.dir(btn.style));
CSSStyleDeclaration
对象有点奇特。如果您直接查看 btn.style["background-color"]
或 btn.style.backgroundColor
,您会看到 red
(或某种红色表示,因浏览器而异)。
const btn = document.querySelector('#btn');
btn.style['background-color'] = 'red';
btn.addEventListener('click', () => {
console.log(btn.style["background-color"]);
console.log(btn.style.backgroundColor);
});
<button id="btn">Click Me</button>
在您显示的控制台输出中,您可以在
backgroundColor
: 下找到它
如果您查看 CSSStyleDeclaration 的规范,您会更多地了解 JavaScript 中 CSS 处理的内部工作原理。
这些是 JS 保存 CSS 样式所采取的步骤:
如果您提供驼峰式版本的属性名称,CSS 属性到 IDL 属性算法会将字符串转换为破折号大小写,以便稍后使用
setProperty(property, value, priority)
方法,property 是属性名称的破折号版本(例如 background-color
),value 是不带 !important
标志的属性应设置的值(例如 "red"
)
属性被推入内部 NodeList 结构,CSSDeclaration,其中包含属性名称、值、重要标志和区分大小写的标志
现在,样式已计算完毕,这主要取决于浏览器的实现,属性顺序和映射逻辑有一定的限制(here),当然元素的行为还有其他规范
现在,要访问这些属性,在内部,既有所有计算属性的数组,也有前面提到的 NodeList,用于通过属性名称获取值。访问这些的方法是
item(index)
。
这就是为什么,当您在控制台上查看 CSSStyleDeclaration 时,顶部有一个
0: "background-color"
,它是该元素的 NodeList 中的第一个(计算的)属性,因此 e.style.item(0)
将返回 "background-color"
。
getPropertyValue(property)
,它会遍历 NodeList 并找到具有相应属性名称的项目并返回其值。
JavaScript 通过对象索引(here)对这些函数有简写,因此
e.style[property]
运行该属性名称的 getPropertyValue()
,并通过 item(index)
方法的数组索引,因此 e.style[index]
运行 item()
方法。
const btn = document.querySelector('#btn');
btn.style['background-color'] = 'red';
btn.addEventListener('click', () => {
console.log(btn.style[0], btn.style.item(0));
console.log(btn.style[btn.style[0]], btn.style.getPropertyValue(btn.style.item(0)));
});
<button id="btn">Click Me</button>
我还偶然发现了
CSSStyleDeclaration
对象的这种意想不到的结构,并想发布我的将 CSSStyleDeclaration
对象转换为 Map<string, string>
的解决方案:
function computedStylesToMap(stylesAsObj){
const map = new Map();
for (let i = 0; i < stylesAsObj.length; ++i) {
const cssPropName = stylesAsObj[i];
const cssPropValue = stylesAsObj.getPropertyValue(cssPropName);
map.set(cssPropName, cssPropValue);
}
return map;
}
const btn = document.querySelector('#btn');
const stylesAsObj = window.getComputedStyle(btn);
const stylesAsMap = computedStylesToMap(stylesAsObj)
// You can use the resulting map to get the property values:
console.log(
"Background color of button is",
stylesAsMap.get("background-color")
);
#btn {
background-color: red;
}
<button id="btn">A Button</button>
注意:此代码使用
getComputedStyle
来获取元素的所有计算样式,但您也可以将其替换为 element.style
,但这样您只能获取通过元素的 style
属性设置的样式,并且不是通过 CSS 设置的样式。