遍历bom主要有两种方式,一种是通过nodeIterator,另一种是通过treeWalker(IE9以下都不支持). 后者是前者的高级版本。
注意在dom中,如果html写成这样:
<div id='A'>
<div id='B'></div>
</div>
那么,divA其实有两个子节点,一个是由回车构成空白文本节点,一个是有divB构成的子节点,这是正常的解析,当然也有不这样认为的,例如低版本ie,它会忽视掉回车构成饿文本子节点,而认为自己只有一个子节点就是divB。
在调用nodeIterator和treeWalker之前,依然需要进行特性检测,已查看是否支持遍历。如果不检测,不兼容的浏览器会报错,说几句不相干的话,今天看了JavaScript DOM高级程序设计的前面几页,讲到说在js编程中,要做到渐进增强和平稳退化,前者是说在有某些高级特性的时候,我们使用高级特性,如果高级特性不支持的情况下,必须保证内容的呈现和可用,即使交互过程可能不再”优雅“。
if(document.implementation.hasFeature('traversel','2.0')) if(typeof document.createNodeIterator=='function')if(typeof document.createTreeWalker=='function').
1.nodeIterator ,document.creatNodeIterator(root,NodeFilter.SHOW_ALL,filter,false);其中root表示开始遍历的根节点,第二个参数表示要访问哪些节点的数字代码,通过NodeFilter类的静态属性来表示,常用的值有NodeFilter.SHOW_ELEMENT,NodeFilter.SHOW_TEXT,NodeFilter.SHOW_ALL,filter通常是一个过滤函数,该函数有一个node参数,该函数通过返回NodeFilter.FILTER_ACCEPT和NodeFilter.FILTER_SKIP来分别表示是遍历还是跳过该节点。
2.treeWalker和nodeIterator类似,区别是后者功能更强大,可以通过parentNode(),firstChild(),lastChild(),nextSibling(),previousSibling()来选择不同的遍历方向,还可以通过currentNode属性返回最近一次遍历的节点。
<!DOCTYPE html>
<html>
<head>
<title>NodeIteratorAndTreeWalker</title>
</head>
<body>
<div id='wrapper'>
<div id='header'>
<p>it is Header.</p>
</div>
<div id='content'>
<p>ello,it is my home! Are you ok?</p>
<ul><li>home</li><li>Index</li><li>Album</li><li>Logs</li>
</ul>
<p><input type="button" value="iteratorBody" οnclick="iteratorBody()"/>
<input type="button" value="treeWalkerBody" οnclick="treeWalkerBody()"/>
</p>
</div>
</div>
<script type="text/javascript">
var filter=function(node){
return node.nodeName.toLowerCase()=='ul'||node.nodeName.toLowerCase()=='li'?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP;
};
var wrapper=document.getElementById('wrapper');
function iteratorBody(){
var bodyIt=document.createNodeIterator(document.body,NodeFilter.SHOW_ALL,filter,false);
var current=bodyIt.nextNode();
while(current!==null){
console.log(current.nodeType+" "+current.tagName);
current=bodyIt.nextNode();//前进到下一个节点
}
}
function treeWalkerBody(){
if(document.implementation.hasFeature("Traversal",'2.0')){
var bodyTreeWalker=document.createTreeWalker(document.body,NodeFilter.SHOW_ELEMENT,null,false);
var p=bodyTreeWalker.firstChild();//遍历到第一个子节点,类似的方法有lastChild(),previousSibling(),nextSibling(),parentNode()
alert(bodyTreeWalker.currentNode.tagName);//返回最近一次遍历的节点的tagName,DIV
bodyTreeWalker.firstChild();
alert(bodyTreeWalker.currentNode.tagName);//DIV
bodyTreeWalker.nextSibling(); //遍历到下一个同辈节点
alert(bodyTreeWalker.currentNode.tagName);//DIV
bodyTreeWalker.firstChild();
alert(bodyTreeWalker.currentNode.tagName);//P
var ul=bodyTreeWalker.nextSibling();
alert(ul.tagName);//UL
}else{
alert( document.body.childNodes[0].nodeType);
}
}
</script></body>
</html>