0

I have several DOM elements in my html with the class "high", I want to get all elements with the "high" class and remove the class from it, I have tried this already (I am using Chrome's console to test the code):

var check= document.getElementsByClassName("high");
for(var k = 0; k < check.length; k++){
    check[k].classList.remove("high");
}

But the problem is that it seems to only remove the class from half the elements in the array and stop. If I do console.log(check); afterwards I can see that the array has had half its elements removed. How ever, this seems to work:

var check= document.getElementsByClassName("high");
while(check.length > 0){
    check[0].classList.remove("high");
}

I would expect the first code to work, but now that the second one is working, I don't know exactly how and why this happens.

SOLVED

The Question was answered, but for those interested in seeing this problem in action:

Here's A Fiddle

  • 1
    That is pretty baffling. Doesn't the second one run away (infinite loop)? – Mr. B Mar 16 '16 at 13:00
  • 2
    Because [`document.getElementsByClassName`](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName) returns an [`HTMLCollection`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection) which is live, and therefore "it is automatically updated when the underlying document is changed." – sgbj Mar 16 '16 at 13:02

2 Answers2

2

document.getElementsByClassName returns a live HTML collection which can cause issues when you iterate over the collection and change some of them.

Use document.querySelectorAll('.high') instead. It returns a static node list and you won't have that problem.

More information on HTML collections/node lists.

Community
  • 1
  • 1
Andy
  • 61,948
  • 13
  • 68
  • 95
1

This is pretty logic indeed :

let's imagine the following array

[0, 1, 2, 3]

you first delete the 0-th item, this gives you

[1, 2, 3]

then, second step you delete the 1-st item (here it is the 2), this gives you

[1, 3]

And you stop there, you should not increment the index when deleted, as all remaining elements are shifted to the left. And you have only deleted half of the items.

yunandtidus
  • 3,847
  • 3
  • 29
  • 42