DOM2定义了两个用于顺序遍历DOM结构的类型:NodeIterator
和TreeWalker
,这两个类型能够基于给定的起点对DOM结构执行深度优先的遍历操作。
NodeIterator
var nodeIterator = document.createNodeIterator(root, whatToShow, filter);
参数:
- root: 遍历起点
- whatToShow: 表示访问哪些节点的数字代码
- filter: 是一个用来选择相关节点的NodeFilter对象,或者一个表示应该接受还是拒绝某种特定节点的函数
方法:parentNode()
移动当前 Node到文档顺序中的第一个“可见”的祖先节点,并返回该节点。firstChild()
移动当前 Node到当前节点的第一个“可见”子节点,并返回该节点。
whatToShow 常用常量:
NodeFilter.SHOW_ALL | 显示所有类型的节点 |
---|---|
NodeFilter.SHOW_ELEMENT | 显示元素节点 |
NodeFilter.SHOW_TEXT | 显示文本节点 |
NodeFilter.SHOW_COMMENT | 显示注释节点 |
NodeFilter.SHOW_DOCUMENT | 显示文档节点 |
NodeFilter.SHOW_DOCUMENT_TYPE | 显示文档类型节点 |
NodeFilter对象
NodeFilter 接口表示一个对象,此对象用于过滤 NodeIterator 或 TreeWalker 中的节点。它既不能处理 DOM,也不能遍历节点;它只能根据提供的过滤器对单个节点进行判定。
方法:NodeFilter.acceptNode()
常量 | 描述 |
---|---|
FILTER_ACCEPT | 当需要接受一个节点时,NodeFilter.acceptNode()返回该值。 |
FILTER_REJECT | 当需要拒绝一个节点时,NodeFilter.acceptNode()返回该值。 对于 TreeWalker,这个节点的子节点也会被拒绝。 对于 NodeIterator,这个常量的表现与FILTER_SKIP一样。 |
FILTER_SKIP | 当NodeIterator或 TreeWalker对象需要跳过一个节点时NodeFilter.acceptNode()返回该值。 但被跳过节点的子节点仍会被考虑,意即“跳过该节点但不包括其子节点”。 |
例:
<div id="div1">
<p>
<b>Hello World</b>
</p>
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
</div>
var div = document.getElementById('#div1');
var iterator = document.createNodeIterator(div, NodeFilter.SHOW_ELEMENT, null);
var node = iterator.nextNode();
while(node !== null){
console.log(node.tagName);
node = iterator.nextNode();
}
// DIV
// P
// B
// UL
// LI
// LI
var div = document.getElementById('#div1');
var filter = function(node){
return node.tagName.toLowerCase() === 'li'
? NodeFilter.FILTER_ACCEPT
: NodeFilter.FILTER_SKIP
}
var iterator = document.createNodeIterator(div, NodeFilter.SHOW_ELEMENT, filter);
var node = iterator.nextNode();
while(node !== null){
console.log(node.tagName);
node = iterator.nextNode();
}
兼容性
TreeWalker
TreeWalker
是NodeIterator
的一个更高级的版本。除了包括nextNode()
和previousNode()
的方法之外,还提供了下列在不同方向上遍历DOM结构的方法:parentNode()
移动当前 Node到文档顺序中的第一个“可见”的祖先节点,并返回该节点。firstChild()
移动当前 Node到当前节点的第一个“可见”子节点,并返回该节点。lastChild()
移动当前 Node到当前节点的最末一个“可见”子节点,并返回该节点。previousSibling()
移动当前 Node到当前节点的前一个兄弟节点,并返回该节点。nextSibling()
移动当前 Node到当前节点的后一个兄弟节点,并返回该节点。previousNode()
移动当前 Node到文档顺序中前一个节点,并返回该节点。nextNode()
移动当前 Node到文档顺序中下一个节点,并返回该节点。
创建:var walker = document.createTreeWalker(root, whatToShow, filter);
当我们知道
var div = document.getElementById('#div1');
var walker = document.createTreeWalker(div, NodeFilter.SHOW_ELEMENT, null);
walker.firstChild(); // 转到<p>
walker.nextSibling(); // 转到<ul>
var node = walker.firstChild(); // 转到第一个<li>
while(node !== null){
console.log(node.tagName);
node = walker.nextSibling();
}