Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change class for all elements retrieved by document.getElementsByClassName

I have a table which contains 3 rows. Each row has the class: .myClass.

I then query for the table rows with document.getElementsByClassName('myClass') and iterate over the elements, changing each row's class to .otherClass.

However,

console.log(document.getElementsByClassName('otherClass'))

only returned one row.

And, when I looked at the DOM, only the first .myClass row had its class changed to .otherClass; the other remained untouched.

How can I change the class of all .myClass rows to .otherClass?

var c = document.getElementsByClassName('myTable')[0];
var x = c.getElementsByClassName('myClass');

for (var i = 0; i < x.length; i++) {
  x[i].className = 'otherClass';
}

x = c.getElementsByClassName('otherClass');

console.log(x);  // only one element
<table class="myTable">
  <tr class="myClass2">
    <td>Content</td>
    <td>Content</td>
  </tr>
  <tr class="myClass">
    <td>Content</td>
    <td>Content</td>
  </tr>
  <tr class="myClass">
    <td>Content</td>
    <td>Content</td>
  </tr>
</table>
like image 403
Mitre Avatar asked Jul 09 '15 08:07

Mitre


2 Answers

getElementsByClassName, like other HTML collections, is "live", that is, when you assign another class name to its member, it's removed from the collection on the fly and its length gets decremented. That's why your loop runs only once.

var x = document.getElementsByClassName('myClass');
alert("before: " + x.length);
x[0].className='otherClass';  
alert("after: " + x.length);
.myClass { color: black }
.otherClass { color: red }
<b class="myClass">hi</b>
<b class="myClass">hi</b>

Docs:

An HTMLCollection in the HTML DOM is live; it is automatically updated when the underlying document is changed.


To answer in context to your question, you could set the className of the first element until there are none left in the collection:

while(x.length > 0) {
   x[0].className = 'otherClass';  
}
like image 126
3 revs, 2 users 83% Avatar answered Oct 04 '22 14:10

3 revs, 2 users 83%


As georg pointed out in his answer, getElementsByClassName returns a "live" collection. That means the array will "update" as the elements change.

To fix your problem, you should use a while loop, iterating while x.length exists, and only changing the first element of the HTMLCollection.

var c = document.getElementsByClassName('myTable')[0];
var x = c.getElementsByClassName('myClass');
while (x && x.length) {
  x[0].className = 'otherClass'
}
var y = c.getElementsByClassName('otherClass'); 
alert(y.length);
.myClass {
  display:block;
  background-color: red;
}
.otherClass {
  display:block;
  background-color:green;
}
<table class="myTable">
<tr class="myClass2">
 <td>Content</td>
 <td>Content</td>
</tr>
<tr class="myClass">
 <td>Content</td>
 <td>Content</td>
</tr>
<tr class="myClass">
 <td>Content</td>
 <td>Content</td>
</tr>
<table>
like image 40
royhowie Avatar answered Oct 04 '22 16:10

royhowie