javascript - 遍历未知 DOM 的递归函数

标签 javascript dom recursion

我正在学习 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>

接下来是流程:

  1. 文档节点
  2. 我们用他的第一个 child 重复这个函数:head node
  3. 我们用他的第一个 child 重复这个功能:元节点
  4. 因为'meta'没有 child ,我们用他的下一个重复这个函数 sibling: 标题节点.
  5. 因为'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/

相关文章:

Php 输出破坏了 Javascript

c# - 未触发 Kendo UI DropDownList Change 事件

javascript - 我需要在 React 应用程序中突出显示搜索到的文本

javascript - 使用 Parse.com 解析 xml/HTML 字符串

python - 从自身内部调用一个函数

javascript - Html 弹出窗口将 PWA 图标添加到电话

c# - 在文本框中输入字符时显示 div 标签内容?

javascript - 使用JS绘制横线

java - 检查两棵树是否相同

python - Recaman 递归