我正在学习 js DOM,我想制作一个递归函数,我可以用它来遍历任何 DOM 中的所有节点 .我成功了,但我不明白为什么我的第一次尝试不起作用:
HTML
function mostrarNodosV2(node) {
console.log(node.nodeName);
if (node.firstElementChild != null) {
node = node.firstElementChild;
mostrarNodosV2(node);
}
if (node.nextElementSibling != null) {
node = node.nextElementSibling;
mostrarNodosV2(node);
}
}
mostrarNodosV2(document);
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Exercise IV</title>
</head>
<body>
<h1> Just a header</h1>
<p>Nice paragraph</p>
<ul>
<li>Im just an element list on an unordered list</li>
</ul>
</body>
</html>
接下来是流程:
- 文档节点。
- 我们用他的第一个 child 重复这个函数:head node。
- 我们用他的第一个 child 重复这个功能:元节点。
- 因为'meta'没有 child ,我们用他的下一个重复这个函数 sibling: 标题节点.
- 因为'title'没有 child 或下一个 sibling ,我们结束 function where node=title,我们应该结束函数where node = meta,我们应该继续检查 head 的下一个兄弟节点:body 节点。
相反,如果您调试或检查控制台,您将看到浏览器重复该部分:
if (node.nextElementSibling != null) {
node = node.nextElementSibling;
mostrarNodosV2 (node);
}
其中 node = meta,因此我们在控制台上打印了两个“TITLE”。然后它就应该消失了,我们得到了“body”节点。 “LI”元素也会出现同样的问题。
所以,我不想要其他解决方案,我只是这样做了,我只是想知道为什么我回到那个“如果”,因为我不明白。
如果你在开发者工具上调试它会更容易理解。
最佳答案
你的递归函数重复节点的原因是因为你重新分配了node
。让我们自己逐步执行该功能:
document -> has a child
html -> has a child
head -> has a child
meta -> has no child, has a sibling
title -> has no child or sibling
head -> head has been overwritten with meta, which has a sibling
title -> has no child or sibling
html -> html has been overwritten with head, which has a sibling
body -> has a child
h1 -> has no child, has a sibling
p -> has no child, has a sibling
ul -> has a child
li -> has no child or sibling
ul -> ul has been overwritten with li, which has no sibling
body -> body has been overwritten with h1, which has a sibling
...
现在你明白为什么覆盖函数参数是不好的了。
如果您想要一种更健壮的方法,这里是我编写递归 DOM 遍历函数的方式:
function mostrarNodosV2(node) {
if (node == null) {
return;
}
console.log(node.nodeName);
mostrarNodosV2(node.firstElementChild);
mostrarNodosV2(node.nextElementSibling);
}
mostrarNodosV2(document);
这里唯一的区别是我检查节点有效性的递归比你对每个节点所做的更深,这减少了你的方法的冗长。
关于javascript - 遍历未知 DOM 的递归函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34796298/