DOM扩展:DOM API的进一步增强[总结篇-上]

DOM1级主要定义了文档的底层结构,并提供了基本的查询操作的API,总体而言这些API已经比较完善,我们可以通过这些API完成大部分的DOM操作。然而,为了扩展DOM API的功能,同时进一步提高DOM操作的效率,DOM扩展也不断被提出和采纳。对DOM的扩展主要有两部分:Selectors API和HTML5,另外还有一个Element Traversal规范,主要用于元素遍历,另外还有一些专有扩展。


1 Selectors API

Selectors API主要实现根据CSS选择符来查询匹配的文档元素,事实上这个功能是很多JavaScript库(如jquery)都提供的功能。selectors API level 1的核心是两个函数:querySelector()querySelectorAll(),这两个方法都接收一个参数,即CSS选择器,前者只返回与选择器匹配的第一个元素,后者则是返回匹配的所有元素的NodeList。这两个函数在使用时需要注意:
(1) 如果传入的选择器是浏览器不支持的或者存在语法错误时,这两个方法都会报错。
(2)可以调用这个方法的节点类型包括Document,Element和DocumentFragment。
Selectors API的浏览器支持情况如下:IE8只能支持CSS2.1中的选择器格式,对于 :nth-child()等CSS3中的选择器是不支持的。


Selectors API LEVEL2增加了一个方法为matchesSelector,用来检查调用元素是否符合传入的css选择器。截止到2011年还没有浏览器真正实现了matchesSelector方法,楼主测试了最新版的chrome和firefox,同样也没有实现这个方法,但是各个浏览器都有实验性的方法,比如IE实现了msMatchesSelector,firefox实现了mozMatchesSelector,safari和chrome实现了webkitMatchesSelector方法,如果需要使用该方法,则需要进行必要的能力检测。

2 Element Traversal API

我们曾介绍过,IE9及以上的浏览器会把元素间的空白或换行也作为parentNode的childNodes属性中的一个item,从而为我们遍历元素造成一定障碍,Element Traversal API为元素增加了以下几个属性:
[1]firstElementChild:第一个孩子元素
[2]lastElementChild:最后一个孩子元素
[3]previousElementSibling:上一个相邻的元素
[4]nextElementSibing:下一个相邻的元素
[5]childElementCount:元素子节点的数目

使用这几个API就不需要考虑文本节点和注释节点所带来的影响了,这样我们遍历一个Element的代码就可以由原来的:
function traversal(element){
var childNodes = element.childNodes,i = 0, len = childNodes.length, item;
for(; i < len ; i++){
item = childNodes.item([i]);
if(item.nodeType === 1){
console.log(item.nodeName + ":" + item.innerHTML);
}
}
}

演变为:


function traversalNewVersion(element){
var len = element.childElementCount, child = element.firstElementChild;
while(true){
console.log(child.nodeName + ":" + child.innerHTML);
if(child === element.lastElementChild){
break;
}
child = child.nextElementSibling;
}
}
注:IE9+,Firefox3.5+,chrome,Opera10+,Safari4+支持Element Traversal API
 
HTML5对DOM节点的扩展

HTML5对DOM节点的操作也增加了一些API,这一节主要介绍HTML5对DOM节点的扩展。

3.1 与类有关的扩展

随着WEB开发的不断发展,出现了一个现象:class运用得越来越多,一方面通过class为元素设置css样式,另一方面class还能代表一定的语义性质,为此,HTML5为DOM的class特性操作确定了相应的扩展,主要包括:
3.1.1 getElementsByClassName
getElementsByClassName可以根据class特性选择元素,返回的是一个NodeList,它接收一个参数,即class特性字符串,class的先后顺序不会影响元素的查找。比如我们的DOM中有如下两个元素:
<p class="red strong">我是第一个段落</p>
<p class="green strong bigger">我是较大的段落</p>
那么我们调用:
var paragraphs = document.getElementsByClassName("strong red");
仍然可以查找到第一个段落元素,
getElementsByClassName的浏览器支持情况如下:

3.1.2 classList属性
HTML中,一个元素可能会有多个class特性,每一个class特性之间用空格分隔,这样如果想要对class特性进行修改或者增加class特性的话,必须对字符串进行处理。大部分JavaScript类库都实现了操作class特性相关的方法,而HTML中为元素增加了一个classList属性,从而可以方便地实现对class特性的操作,这个属性是新集合类型DOMTokenList的实例,它也有一个length属性,同时还定义了如下方法:
(1)add(value):为元素增加一个class类
(2)contains(value):判断元素是否包含一个class
(3)remove(value):删除一个class
(4)toggle(value):如果包含这个类,则删除;如果不包含,则增加。
有了这些方法,我们操作class列表时就非常方便了,classList的浏览器支持情况如下图:

3.2 焦点管理
HTML5中也新增了管理DOM焦点的功能,主要是document的两个属性:
(1)
 
document.activeElement:
这个引用始终指向当前页面取得焦点的元素,页面加载完毕时,它指向document.body。
(2)document.hasFocus:用于获取当前文档是否获得了焦点,从而判断页面是不是正在与用户进行交互。
这两个属性最大的功能是提高web应用的无障碍性。
注:IE4+,Firefox3+,chrome,Opera8+,Safari4+支持这两个属性

3.3 HTMLDocument的变化
HTML5对HTMLDocument也做了扩展,增加了新的属性和功能,这些 变化也是基于大部分浏览器已经完全支持的专有扩展而来,因此虽然这些变化写入标准的时间不长,但是有些浏览器可能很早就已经支持相应的功能了。
 
3.3.1 readyState
IE4首先为document设置了readyState属性,其他浏览器也陆续增加了这个属性,HTML最终将这个属性写入了标准。在IE中,document的readyState属性包括两个值:
[1]loading:正在载入文档
[2]complete:文档加载结束
我们看下标准中对readyState的阐述:
firefoxchrome等浏览器中,loading和complete之间还有一个interactive状态,我们看一下MDN中对interactive状态的阐述:
 
The document has finished loading and the document has been parsed but sub-resources such as images, stylesheets and frames are still loading. The state indicates that theDOMContentLoaded event has been fired.
 
也就是说,文档本身已经被加载完毕,并且也已经被解析完毕,但是像image,css style文件等外部资源还在下载,这时意味着DOMContentLoaded事件的触发。
在readyState状态的改变会触发readystatechange事件,我们可以通过为document绑定
readystatechange事件来监听其状态的变化。
注:IE4+,Firefox3.6+,chrome,Opera9+,Safari支持这两个属性

3.3.2 兼容模式
从IE6开始区分渲染页面的模式是标准还是混杂的,检测页面的兼容模式就成为浏览器的必要功能。IE为此添加了一个compatMode属性用来标识页面渲染是标准模式还是混杂模式。如果是标准模式,这个属性值为"CSS1Compat",而如果是混杂模式,这个属性值为"BackCompat"
除IE为,Firefox,chrome,Opera,Safari3.1+也都实现了这个属性,并最终被HTML纳入标准之中。
 
3.3.3 head属性
document.head可以引用页面中的<head>元素,当然还可以通过document.getElementsByTagName("head")[0]来引用<head>元素。
注:IE10+也支持这个属性
 
3.4 字符集属性
HTML5新增了几个和字符集有关的属性,主要包括:
(1)lcharset:表示文档中实际使用的字符集,这个属性既可以通过<meta>标签来修改,也可以通过返回的http头部设置,还可以修改charset属性来设置。另外,firefox中支持characterSet属性,这个属性是只读的。
注:chrome45之后将charset属性设置成了只读的,IE 8及以下不支持characterSet属性
(2)defaultCharset:默认的字符集是什么,这个属性和浏览器或操作系统的设置有关系。
注:firefox不支持defaultCharset
 
3.5 自定义属性
HTML5规定可以为元素添加非标准的属性,但要添加一个"data-"前缀,目的是提供与渲染无关的信息或提供语义化的信息,比如我们有以下代码:
<div id="div" data-author="刘木林" data-uuid="123" data-age="23"></div>
 
一个元素的自定义属性保存在dataset属性中,这个值是DOMStringMap的实例,也就是一个键值对的映射。在这个映射中,每一个自定义属性都会有一个对应的属性,只不过这个属性名没有了data-前缀,我们仍然以上面的代码为例:
var div = document.getElementById("div");
var data = div.dataset;
console.log(data.author);

输出的结果就是:刘木林

目前dataset属性的支持情况如下:


IE10及以下和opera mini为"Partial support",意思是可以通过getAttribute("data-")来获取自定义属性,比如上例中:
alert(div.getAttribute("data-author"));
那么也会弹出:刘木林

未完待续~~

 

posted @ 2016-01-07 15:09  TracyLin  阅读(1376)  评论(0编辑  收藏  举报