JavaScript高级程序设计之DOM 扩展之HTML5之与类相关的扩充第11.3.1讲

11.3 HTML5
对于传统HTML 而言,HTML5 是一个叛逆。所有之前的版本对JavaScript 接口的描述都不过三言
两语,主要篇幅都用于定义标记,与JavaScript 相关的内容一概交由DOM 规范去定义。
而HTML5 规范则围绕如何使用新增标记定义了大量JavaScript API。其中一些API 与DOM 重叠,
定义了浏览器应该支持的DOM 扩展。
因为HTML5 涉及的面非常广,本节只讨论与DOM 节点相关的内容。HTML5 的
其他相关内容将在本书其他章节中穿插介绍。

11.3.1与类相关的扩充

HTML4 在Web 开发领域得到广泛采用后导致了一个很大的变化,即class 属性用得越来越多,一
方面可以通过它为元素添加样式,另一方面还可以用它表示元素的语义。于是,自然就有很多JavaScript
代码会来操作CSS 类,比如动态修改类或者搜索文档中具有给定类或给定的一组类的元素,等等。为了
让开发人员适应并增加对class 属性的新认识,HTML5 新增了很多API,致力于简化CSS 类的用法。

//取得所有类中包含"username"和"current"的元素,类名的先后顺序无所谓
var allCurrentUsernames = document.getElementsByClassName("username current");
//取得ID 为"myDiv"的元素中带有类名"selected"的所有元素
var selected = document.getElementById("myDiv").getElementsByClassName("selected");

调用这个方法时,只有位于调用元素子树中的元素才会返回。在document 对象上调用
getElementsByClassName()始终会返回与类名匹配的所有元素,在元素上调用该方法就只会返回后
代元素中匹配的元素。
使用这个方法可以更方便地为带有某些类的元素添加事件处理程序,从而不必再局限于使用ID 或标
签名。不过别忘了,因为返回的对象是NodeList,所以使用这个方法与使用getElementsByTagName()
以及其他返回NodeList 的DOM 方法都具有同样的性能问题。
支持getElementsByClassName()方法的浏览器有IE 9+、Firefox 3+、Safari 3.1+、Chrome 和
Opera 9.5+。

2. classList 属性
在操作类名时,需要通过className 属性添加、删除和替换类名。因为className 中是一个字
符串,所以即使只修改字符串一部分,也必须每次都设置整个字符串的值。比如,以下面的HTML 代
码为例。

<div class="bd user disabled">...</div>
这个<div>元素一共有三个类名。要从中删除一个类名,需要把这三个类名拆开,删除不想要的那
个,然后再把其他类名拼成一个新字符串。请看下面的例子。

//删除"user"类
//首先,取得类名字符串并拆分成数组
var classNames = div.className.split(/\s+/);
//找到要删的类名
var pos = -1,
i,
len;
for (i=0, len=classNames.length; i < len; i++){
if (classNames[i] == "user"){
pos = i;
break;
}
}
//删除类名
classNames.splice(i,1);
//把剩下的类名拼成字符串并重新设置
div.className = classNames.join(" ");
为了从<div>元素的class 属性中删除"user",以上这些代码都是必需的。必须得通过类似的算
法替换类名并确认元素中是否包含该类名。添加类名可以通过拼接字符串完成,但必须要通过检测确定
不会多次添加相同的类名。很多JavaScript 库都实现了这个方法,以简化这些操作。
HTML5 新增了一种操作类名的方式,可以让操作更简单也更安全,那就是为所有元素添加
classList 属性。这个classList 属性是新集合类型DOMTokenList 的实例。与其他DOM 集合类似,

DOMTokenList 有一个表示自己包含多少元素的length 属性,而要取得每个元素可以使用item()方
法,也可以使用方括号语法。此外,这个新类型还定义如下方法。
add(value):将给定的字符串值添加到列表中。如果值已经存在,就不添加了。
contains(value):表示列表中是否存在给定的值,如果存在则返回true,否则返回false。
remove(value):从列表中删除给定的字符串。
toggle(value):如果列表中已经存在给定的值,删除它;如果列表中没有给定的值,添加它。
这样,前面那么多行代码用下面这一行代码就可以代替了:

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 (var i=0, len=div.classList.length; i < len; i++){
doSomething(div.classList[i]);
}
有了classList 属性,除非你需要全部删除所有类名,或者完全重写元素的class 属性,否则也
就用不到className 属性了。
支持classList 属性的浏览器有Firefox 3.6+和Chrome。


你可能感兴趣的:(JavaScript,js,DOM扩展,JS基础知识)