这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战
自
HTML4
被广泛采用以来,Web
开发中一个主要的变化是class
属性用得越来越多,其用处是为元素添加样式以及语义信息。为了适应开发者和他们对class
属性的认可,HTML5
增加了一些特性以方便使用CSS
类。
1. getElementsByClassName()
getElementsByClassName()
是 HTML5
新增的最受欢迎的一个方法,暴露在 document
对象和所有 HTML
元素上。这个方法脱胎于基于原有 DOM
特性实现该功能的 JavaScript
库,提供了性能高好的原生实现。
getElementsByClassName()
方法接收一个参数,即包含一个或多个类名的字符串,返回类名中包含相应类的元素的 NodeList
。如果提供了多个类名,则顺序无关紧要。下面是几个示例:
// 取得所有类名中包含"username"和"current"元素
// 这两个类名的顺序无关紧要
let allCurrentUsernames = document.getElementsByClassName("username current");
// 取得 ID 为"myDiv"的元素子树中所有包含"selected"类的元素
let selected = document.getElementById("myDiv").getElementsByClassName("selected");
如果要给包含特定类(而不是特定 ID
或标签)的元素添加事件处理程序,使用这个方法会很方便。不过要记住,因为返回值是 NodeList
,所以使用这个方法会遇到跟使用 getElementsByTagName()
和其他返回 NodeList
对象的 DOM
方法同样的问题。
2. classList 属性
要操作类名,可以通过 className
属性实现添加、删除和替换。但 className
是一个字符串,所以每次操作之后都需要重新设置这个值才能生效,即使只改动了部分字符串也一样。以下面的 HTML
代码为例:
<div class="bd user disabled">...</div>
这个 <div>
元素有 3
个类名。要想删除其中一个,就得先把 className
拆开,删除不想要的那个,再把包含剩余类的字符串设置回去。比如:
// 要删除"user"类
let targetClass = "user";
// 把类名拆成数组
let classNames = div.className.split(/\s+/);
// 找到要删除类名的索引
let idx = classNames.indexOf(targetClass);
// 如果有则删除
if (idx > -1) {
classNames.splice(i,1);
}
// 重新设置类名
div.className = classNames.join(" ");
HTML5
通过给所有元素增加 classList
属性为这些操作提供了更简单也更安全的实现方式。classList
是一个新的集合类型 DOMTokenList
的实例。与其他 DOM 集合类型一样,DOMTokenList
也有 length
属性表示自己包含多少项,也可以通过 item()
或中括号取得个别的元素。此外,DOMTokenList
还增加了以下方法。
add(value)
,向类名列表中添加指定的字符串值value
。如果这个值已经存在,则什么也不做。contains(value)
,返回布尔值,表示给定的value
是否存在。remove(value)
,从类名列表中删除指定的字符串值value
。toggle(value)
,如果类名列表中已经存在指定的value
,则删除;如果不存在,则添加。replace(old, new)
,如果类名列表中已经存在指定的old
,则替换成new
;如果不存在,则什么也不做。
这样以来,前面的例子中那么多行代码就可以简化成下面的一行:
div.classList.remove("user");
这行代码可以在不影响其他类名的情况下完成删除。其他方法同样极大地简化了操作类名的复杂性,如下面的例子所示:
// 删除"disabled"类
div.classList.remove("disabled");
// 添加"current"类
div.classList.add("current");
// 切换"user"类
div.classList.toggle("user");
// 检测类名
if (div.classList.contains("bd") && !div.classList.contains("disabled")){
// 执行操作
)
// 迭代类名
for (let class of div.classList){
doStuff(class);
}
// 将类值 "foo" 替换成 "bar"
div.classList.replace("foo", "bar");
添加了 classList
属性之后,除非是完全删除或完全重写元素的 class
属性,否则 className
属性就用不到了。
引用
- [1] JavaScript高级程序设计(第4版)
- [2] MDN Web Docs