Recursive function for passing unknown DOM

I learn about js DOM , and I want to make a recursive function that I could use for , to go through all the nodes in any DOM , I did this, but I can not understand why my first attempt does not work:

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> 

Next thread:

  • document node .
  • we repeat the function with our first child: head node .
  • we repeat the function with our first child: meta node .
  • because of 'meta' has no children, we repeat the function with its next sibling: title node .
  • because of the "title" there are no children or the next brother, we end where node = title, we have to end the function where node = meta, and we have to continue checking the next brother of the head: body node .

Instead , if you are debugging or checking the console, you will see the browser repeating the section:

 if (node.nextElementSibling != null) { node = node.nextElementSibling; mostrarNodosV2 (node); } 

Where node = meta and , therefore, we get two "TITLE" printed on the console . Then it goes as it should be, and we get the "body" node. The same problem occurs with the "LI" element.

So, I don’t want another solution, I just did it, I just want to know why I will return to this β€œif”, because I do not understand this.

If you debug it on developer tools, it will be easier to understand.

+5
source share
3 answers

The reason the recurring functions of the recursive function were related to the fact that you reassigned the node . Let yourself step through the function:

 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 rewriting a function argument is bad.

If you need a more robust approach, here's how I would write 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 that I am checking the validity of the node one recursion deeper than you were for each node, which reduces the verbosity of your approach.

+4
source

you reassign the node variable, try the following:

 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); 
+3
source

No need to implement your own, TreeWalker DOM Level 2 API allows you to bypass traffic by choosing a custom node launch and changing direction.

+1
source

Source: https://habr.com/ru/post/1240634/


All Articles