We are all accustomed to use loops while walking
the DOM structure with JavaScript. We can either use a for
or a do...while
loop for that purpose. Usually we initialize an
index and then we use it to loop through a DOM collection of nodes, such as that returned by getElementsByTagName()
or childNodes
.
I see this pattern over and over in many scripts I studied so far. Recently I read the JavaScript guide by David Flanagan who, talking about the DOM
in the 17th chapter of his guide, proposed an alternate method:
for(var m = n.firstChild; m != null; m = m.nextSibling) { // code here }
Where m
is the node from which we start walking the DOM. Basically, this construct takes advantage of the syntax of the for
loop.
First comes the initial condition, then the internal check on each loop and finally the updated condition. So the above code means:
- start with the very first child of a given node
- is this node different from
null
? - move to the next node.
David proposed a practical example. I've tested it and it works just fine. It is as follows (slightly adapted):
function characters(node) { if(node.nodeType == 3) { return node.length; } var chars = 0, i; for(i = node.firstChild; i != null; i = i.nextSibling) { chars += characters(i); } return chars; }
Testing it gives no surprises:
<head> <script type="text/javascript"> window.onload = function() { var test = document.getElementById('test'); alert(characters(test)); // 33 }; </script> </head> <body> <p id="test">Lorem ipsum dolor sit amet. <span>Lorem</span></p> </body>
What bothers me is performance. How this solution affects it? I need more tests to know.