DOM与样式
elem.className 与 elem.classList
className
对于修改元素的样式,首选修改类名的方式修改样式。
elem.className
对应于标签的 class attribute
,如果我们修改一个 DOM 节点对象的 className
属性,那么会对标签的 class attribute
内容进行直接替换。
classList
elem.classList
是一个类数组,可以获取到一个元素的多个类名。
const div = document.createElement("div");
div.className = "class1 class2 class3";
div.classList; // ["class1", "class2", "class3"]
此时 div.classList
的结构如下:
0: "class1"
1: "class2"
2: "class3"
length: 3
value: "class1 class2 class3"
该类数组上还有如下方法。
方法 | 说明 |
---|---|
elem.classList.add(class) | 给当前元素添加指定类名 |
elem.classList.remove(class) | 给当前元素移除指定类名 |
elem.classList.toggle(class) | 如果类名存在则移除,类名不存在则添加 |
elem.classList.contains(class) | 判断是否还有某个类名 |
elem.classList.replace(oldClass, newClass) | 将旧类名替换为新类名 |
elem.classList.forEach(callback, thisArg) | 遍历 classList |
修改 DOM 元素样式
elem.style
elem.style
是一个只读对象,我们修改 elem.style
上的属性,等价于给对应标签通过 style attribute
添加内联样式。
比如,elem.style.width = "100px"
等价于 <div id="elem" style="width: 100px;"></div>
。
在 elem.style
对象上的样式属性都是以驼峰命名方式存在的。
background-color => elem.style.backgroundColor
z-index => elem.style.zIndex
border-left-width => elem.style.borderLeftWidth
如果你想删除(重制)一个内联样式,你可以将 elem.style
上相应的属性赋值为空字符串。
注意事项
- 使用
elem.style.xxx
添加某个内联样式时注意不要忘记将 CSS 单位添加到值上 - 对于一些简写属性,比如
elem.style.margin
,我们对其赋值后,浏览器会推断出elem.style.marginLeft/Right/Top/Bottom
的值
elem.style.cssText
我们不能像这样 elem.style = "color: red; width: 100px"
设置完整的属性,因为 div.style
是一个对象,并且它是只读的。
但是我们可以使用 elem.style.cssText
来读写标签上的 style attribute
。
elem.style.cssText = `
color: red !important;
background-color: yellow;
width: 100px;
text-align: center;
`;
我们很少使用这个属性,因为这样的赋值会重制整个内联样式。
我们也可以使用 elem.setAttribute("style")
来实现相同效果。
elem.setAttribute("style", `
color: red !important;
background-color: yellow;
width: 100px;
text-align: center;
`);
读取 DOM 元素样式计算值
window.getComputedStyle
window.getComputedStyle(element[, pseudo])
elem.style
的作用仅仅是对一个元素的内联样式进行读写。如果我们想要获取到一个元素所有层叠样式的 计算值 则可以使用 window.getComputedStyle
方法。
<body>
<style>
div {
color: green;
font-size: 1.15rem;
}
</style>
<div style="color: red">Hello World</div>
<div>Hello World</div>
</body>
<script>
const elems = document.querySelectorAll("div");
window.getComputedStyle(elems[0]).color; // 'rgb(255, 0, 0)' 红色
window.getComputedStyle(elems[1]).color; // 'rgb(0, 128, 0)' 绿色
window.getComputedStyle(elems[1]).fontSize; // '18.4px'
</script>
什么是样式的计算值?
比如我们给根元素设置了 font-size: 2rem
,这样的相对单位的取值,最终会被浏览器解析为 px
单位的数值,这个就是计算值,在 Chrome 开发者工具中选中某个元素后,切换到 Computed
就可以查看这个元素所有样式的计算值了。
该方法还有第二个可选参数,用于指定某个元素的 伪元素 或者 伪类,这样我们就可以获取某个元素的 伪元素 或者 伪类 的计算样式了。
<body>
<style>
div::after {
content: "123";
color: green;
font-size: 1.15rem;
}
div:hover {
color: red;
}
</style>
<div>Hello World</div>
</body>
<script>
const elem = document.querySelector("div");
window.getComputedStyle(elem, "::after").content; // '123'
window.getComputedStyle(elem, ":hover").color; // 'rgb(0, 0, 0)' 黑色
</script>
关于元素的伪类
上面的例子中,div:hover
的 color
计算值依旧是黑色,原因是执行该行代码时,我们的鼠标并没有悬浮在 div 元素之上,如果我们悬浮在 div 元素之上,再执行该行元素,那么 color
计算值就会变成红色。
由于隐私问题,链接的 :visited
伪类样式被隐藏了。
不要直接读取 width 和 height 属性
如果你想获取一个元素的尺寸,请可以使用 clientWidth
或 offsetWidth
(后面会讲到)。
如果你直接使用 window.getComputedStyle(elem).width
,那么对于一个内联元素来说取值可能就是 auto
,并且如果元素具有滚动条,那么 width
实际上还会减去滚动条的宽度,因为本质上我们使用该方法读取的是 content
的 width
和 height
,而且这个还和 box-sizing
的取值有关。