JavaScript 样式
通常有两种设置元素的样式
- 为元素添加类属性,如
<div class="...">
,(在内联样式表/外联样式表中)基于该类使用使用 CSS 设置样式 - 将属性直接写入元素,使用属性
style
设置样式,如<div style="color: white; background-color: green;">
。
JavaScript 既可以修改类(使用元素节点属性 className
或 classList
更改 DOM 对象的类是脚本中最常见的操作之一),也可以修改 style 属性(使用元素节点属性 style
),因此可以通过这两种方式设置元素样式。但相较于将样式写入 style
属性,应该首选通过 CSS 类的方式来添加样式,使页面样式设置和页面结构分离,这样更灵活,更易于支持。
className
节点属性 elem.className
对应于其 HTML 元素的 "class"
特性。
<body class="main page">
<script>
alert(document.body.className); // main page
</script>
</body>
Tip
如果对 elem.className
进行赋值,它将替换类中的整个字符串,即如果元素具有多个类属性,全部都会被覆盖。
classList
如果希望操作单个类属性值,可以使用节点属性 elem.classList
返回包含元素所有类属性的对象,它是一个可迭代对象,调用该对象的方法可以添加/删除单个类
elem.classList.add/remove(class)
添加/移除类elem.classList.toggle(class)
如果类不存在就添加类,存在就移除它(一般用于切换样式表示不同状态)elem.classList.contains(class)
检查给定类,返回true/false
<body class="main page">
<script>
// 添加一个 class
document.body.classList.add('article');
alert(document.body.className); // main page article
// 迭代输出所有类属性值
for (let name of document.body.classList) {
alert(name);
// main
// page
// article
}
</script>
</body>
style
节点属性 elem.style
对应于元素 HTML 特性 "style"
,返回设置的样式内容。
它是一个对象,可以通过调用不同的属性设置样式,如 elem.style.width="100px"
的效果等价于我们在 style
特性中有一个 width:100px
字符串。
// 设置 body 背景色
document.body.style.backgroundColor = prompt('background color?', 'green');
Tip
对于多词 multi-word 样式属性,使用驼峰式 camelCase(因为 JavaScript 标识符中不能使用连字符 -
)
- HTML 特性
background-color
=> 节点对象属性elem.style.backgroundColor
- HTML 特性
z-index
=> 节点对象属性elem.style.zIndex
- HTML 特性
border-left-width
=> 节点对象属性elem.style.borderLeftWidth
Tip
标识浏览器的前缀属性,如 -moz-border-radius
和 -webkit-border-radius
,也遵循同样的规则,其中连字符 -
表示大写
button.style.MozBorderRadius = '5px';
button.style.WebkitBorderRadius = '5px';
Warning
使用 style.*
格式进行赋值分别设置不同的一种样式属性,而不能像这样的 div.style="color: red; width: 100px"
一次设置完整的属性。可以使用 style
对象的特殊属性 style.cssText
但是很少使用这个属性,⚠️ 因为通过该方法赋值设置样式会删除/覆盖原来所有的样式,它不是进行添加而是替换它们,可能会删除所需的内容。
类似地,可以使用节点属性 div.setAttribute('style', 'color: red...')
设置元素特性 style
实现相同的功能,但不会删除/覆盖原有的样式,而是添加新样式(除非原来已有同名的样式属性)。
<div id="div">Button</div>
<script>
// 我们可以在这里设置特殊的样式标记,例如 "important"
div.style.cssText=`color: red !important;
background-color: yellow;
width: 100px;
text-align: center;
`;
alert(div.style.cssText);
</script>`
Warning
以上设置样式的方法,其特性参数总是字符串
getComputedStyle
当元素的样式是通过类属性在样式表中进行设置时,通过节点属性 elem.style
无法直接读取相应的样式设置,因为 style
属性仅对应于 HTML 元素的 "style"
特性(attribute)值,而没有任何 CSS 级联 cascade。需要使方法getComputedStyle()
「计算」出应用于元素上的样式,返回一个具有样式属性的对象,可以通过调用该对象相应的属性访问/设置样式属性值。
getComputedStyle(element, [pseudo])
Announce
参数说明:
element
需要被读取样式值的元素pseudo
伪元素(如果需要),如::before
,空字符串或无参数则意味着元素本身
<head>
<style> body { color: red; margin: 5px } </style>
</head>
<body>
<script>
let computedStyle = getComputedStyle(document.body);
// 现在我们可以读取它的 margin 和 color 了
alert( computedStyle.marginTop ); // 5px
alert( computedStyle.color ); // rgb(255, 0, 0)
</script>
</body>
Tip
计算 (computed) 样式值是所有 CSS 规则和 CSS 继承都应用后的值,这是 CSS 级联(cascade)的结果(允许使用相对单位,因为这些属性样式是基于父元素的对应样式值进行设置的)它看起来像 height:1em
或 font-size:125%
。
而解析 (resolved) 样式值是最终应用于元素的样式值值,浏览器将解析计算(computed)值,并使所有单位均为固定的绝对单位,如 height:20px
或 font-size:16px
(对于几何属性,解析值可能具有浮点,如:width:50.5px
)。很久以前方法 getComputedStyle
获取计算(computed)值,但解析值要方便得多,标准也因此发生了变化,所以现在方法 getComputedStyle
实际上返回的对象中的属性值是解析值。
Warning
使用方法 getComputedStyle
访问样式属性值需要完整的属性名,而不应该使用简写属性,虽然没有标准的规则。
如对于 getComputedStyle(elem).padding
什么都没有,而应该使用 paddingLeft/paddingTop
属性。
<style>
body {
margin: 10px;
}
</style>
<script>
let style = getComputedStyle(document.body);
alert(style.margin); // 在 Firefox 中是空字符串
</script>
Warning
使用 CSS 伪类 :visited
对被访问过的链接进行着色。但出于隐式保护考虑,方法 getComputedStyle
没有给出访问链接在该状态下的颜色的方式,否则任何页面都可以在页面上创建它(以迷惑用户),或通过检查样式来确定用户是否访问了某链接。JavaScript 看不到 :visited
所应用的样式,此外 CSS 中也有一个限制,即禁止在 :visited
中应用更改几何形状的样式。这是为了确保一个不好的页面无法测试链接是否被访问,进而窥探隐私。