dede
dede

Reputation: 1

Why can't I change the className of a defined element

I simply want to remove one class of some elements without any framework like jQuery. First I tried it with a for(... in ...) than change ist to a for(var i...) but now I found out that not even a direct selection doesn't work.

With jQuery it works fine. But it's... let's say for explaining what jQuery does.

My Script:

[109] <script>
[110]   var hidden = document.getElementsByClassName('hidden');
[111]   console.log('Class "hidden" size: ' + hidden.length);
[112]   console.log(hidden[0].tagName);
[113]   console.log(hidden[1].tagName);
[114]
[115]   hidden[0].className = '';
[116]   hidden[1].className = '';
[117] </script>  

The console log:

Class "hidden" size: 2
H1
FORM
Uncaught TypeError: Cannot set property 'className' of undefined(anonymous function) @ login.html:116

Why can I get the tagName of hidden[1] but not change its className but for hidden[0].

When I change the order to

[115]   hidden[1].className = '';
[116]   hidden[0].className = '';

so hidden[1] is before hidden[0] it works.

It looks like var hidden = document.getElementsByClassName('hidden'); will be run a second time when the first selected element has been changed and the length of the element getting smaller.

Upvotes: 0

Views: 207

Answers (1)

James Allardice
James Allardice

Reputation: 165971

getElementsByClassName returns a live NodeList which means the elements it contains changes as the DOM changes. You remove the relevant class name from an element in that set and the element will be automatically removed from the set.

For this reason you should iterate over the elements backwards:

for ( var i = hidden.length - 1; i > -1; i-- ) {
  hidden[ i ].className = '';
}

On the first iteration the collection will contain 2 elements (at indices 0 and 1). You remove the class from the element at index 1 and that element is removed from the collection. On the next iteration there is only one element left in the collection but since i has decremented to 0 you are able to reference it correctly.

Edit

As suggested in the comments you could also repeatedly modify hidden[0]:

while ( hidden.length ) {
  hidden[ 0 ].className = '';
}

Upvotes: 3

Related Questions