I am learning about js DOM and I want to make a recursive function that I could use to go through all nodes in any DOM. I made it, but I can not figure out why my first attempt is not working:
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>
The flow is next:
Instead of that, if you debug or check the console you will see that browser repeats the section:
if (node.nextElementSibling != null) {
node = node.nextElementSibling;
mostrarNodosV2 (node);
}
Where node = meta, and so we get two 'TITLE' printed on console. Then it goes as it should have gone, and we get the 'body' node. The same problem happens with the 'LI' element.
So, I do not want another solution, I just did it, I just want to know why I go back to that 'if', because I don't get it.
If you debug it on developer tools it would be easier to understand.
The reason why your recursive function repeated nodes was because you reassigned node
. Let's step through the function ourselves:
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
...
So now you understand why it's bad to overwrite the function argument.
If you would like a more robust approach, here is how I would have written a recursive DOM traversal function:
function mostrarNodosV2(node) {
if (node == null) {
return;
}
console.log(node.nodeName);
mostrarNodosV2(node.firstElementChild);
mostrarNodosV2(node.nextElementSibling);
}
mostrarNodosV2(document);
The only difference here is I'm checking the node validity one recursion deeper than you were for each node, which reduces the verbosity of your approach.
you are re-assigning node
variable, try this:
function mostrarNodosV2(node) {
console.log(node.nodeName);
if (node.firstElementChild != null) {
var child = node.firstElementChild;
mostrarNodosV2(child);
}
if (node.nextElementSibling != null) {
var sibling = node.nextElementSibling;
mostrarNodosV2(sibling);
}
}
mostrarNodosV2(document);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With