Javascript Element.style CSSStyleDeclaration 对象的属性看起来很奇怪?

问题描述 投票:0回答:3

假设我在 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));

javascript html css
3个回答
4
投票

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
:

下找到它


3
投票

如果您查看 CSSStyleDeclaration 的规范,您会更多地了解 JavaScript 中 CSS 处理的内部工作原理。

这些是 JS 保存 CSS 样式所采取的步骤:

  1. 如果您提供驼峰式版本的属性名称,CSS 属性到 IDL 属性算法会将字符串转换为破折号大小写,以便稍后使用

  2. 调用

    setProperty(property, value, priority)
    方法,property 是属性名称的破折号版本(例如
    background-color
    ),value 是不带
    !important
    标志的属性应设置的值(例如
    "red" 

  3. 属性被推入内部 NodeList 结构,CSSDeclaration,其中包含属性名称、值、重要标志和区分大小写的标志

  4. 现在,样式已计算完毕,这主要取决于浏览器的实现,属性顺序和映射逻辑有一定的限制(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>


0
投票

我还偶然发现了

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 设置的样式。

© www.soinside.com 2019 - 2024. All rights reserved.