The first statement is the function definition:
var walk_the_DOM = function walk(node, func) {
...
};
This assigns a function to walk_the_DOM. This function takes in two parameters: node, and func. node is the node you want to work on and func is the function you want to apply on node.
The first line of the function is func(node);. This essentially means you are applying a passed-in function on node. For example, if you called walk_the_DOM like this:
walk_the_DOM(root, function(node) {
console.log(node);
});
You would be calling
function(node) {
console.log(node);
}
on every node, which as the effect of printing out every node in the tree.
The next line node = node.firstChild; basically reassigns the node to its first child. The reason you need to do this is because you need to look at each child of the current node. Of course, you also need to look at the children of those children, but we'll get to that part later.
Now we get to the while loop. The condition on this while loop is just while(node), which just means that the loop will run as long as node is not null or undefined. In our previous statement we did node = node.firstChild. What if the current node has no children? Then node.firstChild will be null and so we won't even enter the loop. We will fall out of it and exit the function (remember this part; we exit the function if the current node has no children. This is know as the stopping condition of our recursive function).
Now inside the while loop, we make our recursive call: walk(node, func);. Let's ignore what happens here for a second and move onto the next line: node = node.nextSibling;. Here we're assigning the next sibling of the node back into the variable node. In effect we are iterating over the siblings of this node. Now what if the node has no other sibling (i.e., the parent node only has one child)? Then node will be null and we will fall out of the loop.
Now let's get back to the recursive call walk(node, func). In the recursive call we call the function itself, which means that the behavior of the function is exactly the same as it was for this iteration. You might think at this point "But doesn't that mean that this will execute forever?". But it won't! Why? Remember the stopping condition I mentioned earlier? At some point you will pass in a node that has no children which means that the recursive call will exit and come back to the next line (node = node.nextSibling) and execution will proceed normally. Now if you think of the DOM as a tree (which it is), what this means is that you will travel as far down one branch as you can and once you reach the end, you fall back up one level, and check to see if there are any other siblings. If there are, you go down that branch as far as you can go. If not, you fall back up one more level and do the check again. In this way, you are able to traverse the entire DOM tree.