// This won't work the way you expect it to! var elements = document.getElementsByClassName('highlighted'); for (var i = 0; i < elements.length; ++i) elements[i].setAttribute('class', 'normal');
The problem is that “elements” is not your normal everyday array. When you change the class for one of the elements from “highlighted” to “normal” the elements object is updated to remove that element. So, the next element you were going to change slips down into the position that was previously occupied by the one you just changed and you end up missing it with your loop. Only every other element gets modified. The fix is to run the loop backwards:
for (var i = elements.length - 1; i >= 0; --i) elements[i].setAttribute('class', 'normal');
Also, keep in mind that Internet Explorer (as of version 9) doesn’t have getElementsByClassName(), so you’ll have to write your own. You can test to see if the browser lacks the function by comparing document.getElementsByClassName to null (current versions of Firefox, Chrome, Opera, and Safari all have it).
Hi quick question,
What if I am fetching using querySelectorAll instead? That also returns an array, but does it need to be looped through backwards like getElementsByClassName does?
I just tried it on several browsers (Firefox, Konqueror, Chrome, Opera, Safari, and IE) and querySelectorAll() does NOT need the backwards loop for any of them. I don’t know if there is a spec that guarantees that it avoids the issue that getElementsByClassName() has, but it seems to be safe with current browser implementations.
spent so many hours trying to work this out and couldn’t find a solution