编写一个名为nextNode的函数,该函数可用于遍历DOM树的所有节点。该函数应将节点作为参数,并返回树中的下一个节点。例如,以下循环将访问每个节点一次,并且只访问一次:
var node = document.body;
do {
node = nextNode(node);
} while (node != null)
我认为从DOM来看,它应该只使用firstChild, lastChild, previousSibling, nextSibling,
和parentNode
。
下面的代码应该是我想象它的工作方式。问题在于childNodes,似乎需要for / while循环才能工作。但循环需要以某种方式记住最后一个childNodes位置并添加i + 1,因为它在do / while循环中调用。我不知道给那里什么条件,我得到无限循环。
nextNode = function(node) {
// for/while loop?
if (node.childNodes) {
}
else if (node.nextSibling) {
node = node.nextSibling;
}
else {
node = node.parentNode.nextSibling;
}
return node;
};
除非我完全错了。有人可以详细说明或指出我正确的方向吗?
答案 0 :(得分:2)
您可以使用此功能:
var nextNode = function(node, deeperDone) {
return !node ? undefined
: node.childNodes.length && !deeperDone ? node.childNodes[0]
: node.nextSibling ? node.nextSibling
: nextNode(node.parentNode, 1);
};
它使用递归来通过父级进行回溯,因为下一个节点可能是层次结构中的几个级别。
这是一个演示:
var nextNode = function(node, deeperDone) {
return !node ? undefined
: node.childNodes.length && !deeperDone ? node.childNodes[0]
: node.nextSibling ? node.nextSibling
: nextNode(node.parentNode, 1);
};
for (var node = document.getElementById('a'); node; node = nextNode(node)) {
if (node.id) console.log(node.id); // skip text nodes
}

<div id="a">
<div id="b"></div>
<div id="c">
<div id="d"></div>
</div>
<div id="e">
<div id="f">
<div id="g"></div>
<div id="h"></div>
<div id="i"></div>
</div>
<div id="j">
<div id="k"></div>
<div id="l"></div>
</div>
</div>
<div id="m"></div>
</div>
&#13;
虽然你要求一个以节点为参数的函数,但是有一个TreeWalker
对象(Orial引用),这是一种游标,你可以在其上调用nextNode
方法反复以步行顺序通过节点。请注意,在开始时,在移动到下一个节点之前,您也希望对root
节点执行某些操作,您可以(在开始时)使用currentNode
属性进行访问:
var walker = document.createTreeWalker(document.getElementById('a'),
NodeFilter.SHOW_ELEMENT);
do {
console.log(walker.currentNode.id);
} while (walker.nextNode());
&#13;
<div id="a">
<div id="b"></div>
<div id="c">
<div id="d"></div>
</div>
<div id="e">
<div id="f">
<div id="g"></div>
<div id="h"></div>
<div id="i"></div>
</div>
<div id="j">
<div id="k"></div>
<div id="l"></div>
</div>
</div>
<div id="m"></div>
</div>
&#13;
答案 1 :(得分:0)
使用createTreeWalker编写树步行者是微不足道的:
function iterateAll() {
return document.createTreeWalker(document);
}
var nodes = iterateAll(), node;
while(node = nodes.nextNode()) {
console.log(node + '');
}