tadhg.com
tadhg.com
 

DOM ‘Live’ Iteration Gotchas

23:17 Sat 24 Mar 2007. Updated: 23:45 25 Mar 2007
[, , ]

When you’re manipulating the DOM and are working with elements through list or array iterators, it’s important to remember that the arrays/lists are “live”—otherwise you’ll end up spending a lot of time trying to figure out why your code is, for example, skipping nodes.

So if you’re going through, say, a list of span elements and removing them, you might try something like:

for (var i = 0, i<spans.length, i++) {
        var thisSpan = spans[i];
        thisSpan.parentNode.removeChild(thisSpan);
}

Your expectation would be the elimination of all the elements passed in. But every time you remove one, it disappears from the array, thus changing the array length, so the “next” item in the array now has a position equal to the position of the item you just removed—but your for loop doesn’t know that, and goes on to position + 1, this “skipping” an item.

This is NOT a JavaScript-only problem, and will occur when you’re doing DOM manipulation in any language.

A simple way to fix this is to just go backwards:

for (var i = (spans.length-1), i >= 0, i--) {
        var thisSpan = spans[i];
        thisSpan.parentNode.removeChild(thisSpan);
}

This will also occur when you’re moving nodes around—usually if you’re dealing with child nodes. So if the spans above were all child nodes of some element, and instead of removing them you were appending them to some other element, you would run into the same problem, because the list is “live” and you would have moved items out of it, with the same effect on array length and item position as when you’re deleting.

Leave a Reply