我是 JavaScript 的新手。我在一本书中找到了这个例子。本章讨论了节点类型,但没有彻底解释该示例。我需要帮助来了解测试函数中的 while 循环中发生的情况。
我的理解是,当父元素不再具有子元素时,while 循环结束。但是程序是否等到找不到子元素,从而允许它控制台日志节点?我不知道顺序是什么。
如果有人能用通俗的语言向我解释这个功能是如何运作的,我将不胜感激。
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript</h1>
<h2><img><a><span></span></a></img></h2>
<h3><img></img></h3>
<script>
function testing(node){
if(node.nodeType == node.ELEMENT_NODE){
console.log(node.tagName);
node = node.firstChild;
while(node){
testing(node)
node = node.nextSibling;
console.log(node);
}
}
}
let boom = document.querySelector("h2");
testing(boom);
</script>
</body>
</html>
递归通常用于简化问题;这里正好相反。
理解这一点的最简单方法是实际遍历函数。
1.以h2
开头为第一node
,检查是否为node
并记录。
2.分配node(h2 currently)
的第一个子项,img
给node
。
3.在while条件下检查node
,如果是:使用node(img)
调用测试,记录img
。
(# 这里我们输入递归)
#4.分配给node
img
的第一个子项,即null
, 所以我们省略了循环。
(#here 我们退出递归并且node
包含img
)
5.分配img
的下一个同级,即a
,日志<a><span></span><a>
。
6.检查node
在while条件下,如果是:使用node(a)
调用测试。
(# 这里我们输入递归)
#7a
的日志标签名是A
,得到a
的第一个子级,即span
。
(##这里我们输入递归)
##8日志标签名 OSspan
SPAN
,将span
的第一个子项分配给node
null
。
##9在 while 条件下检查node
,如果为假:我们又回到了node
span
。
##10分配span
的下一个同级,即空,记录它。
##11在 while 条件下检查node
,如果为 false:我们回到带有a
的递归调用。
(##here 我们退出递归)
#12将a
的下一个同级分配给节点,这是空的。
#13在 while 条件下检查node
,如果为 false:退出带有"a"的递归调用。
(#here 我们退出递归)
14结束函数调用。
#(表示递归级别)
希望这有所帮助,但理想情况下,您应该自己调试代码并逐步完成。
为此,您可以将文件拆分为索引.html和索引.js,在索引中写入<script src="index.js"></script>
.html并通过在 chrome 调试器中的let boom...
行上放置断点来完成此操作。
该脚本正在运行一个递归函数,遍历 HTML 节点。 它向下钻取 DOM 结构,直到找不到子元素,然后浏览兄弟姐妹列表,直到可以找到另一个子元素(通过递归函数),并重复查找更多子元素 输出为
H2 (First element)
IMG (Child of H2)
<a>…</a> (Sibling of IMG)
A (First element of sibling)
SPAN (Child of A)
null
null
null
null
null
null
末尾的空值是满足递归退出条件并打印出没有有效元素的结果
最初它令人困惑,因为 IMG 看起来像它有一个子 () 但 HTML 是这样呈现的
<h2>
<img>
<a>
<span>
</span>
</a>
</h2>
为了充分理解,我会看看递归是什么
https://www.geeksforgeeks.org/recursion/
并阅读节点元素是什么,以了解脚本本身正在运行的内容 https://developer.mozilla.org/en-US/docs/Web/API/Node