Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript className property only updates alternate list items

Tags:

javascript

I tried the following code :

var a = document.getElementsByClassName("cc");
for (var i = 0; i < a.length; i++) {
  a[i].className = "cd";
}
.cc {
  background-color: blue;
}

.cd {
  background-color: chartreuse;
}
<ul>
  <li class="cc">A</li>
  <li class="cc">B</li>
  <li class="cc">C</li>
  <li class="cd">D</li>
</ul>

This only updates the alternate list items and not all of them having the same class. I would like to know the reason why this isn't working.

like image 366
Gaurav Mandhyan Avatar asked Mar 20 '21 07:03

Gaurav Mandhyan


1 Answers

Issue

.getElementsByClassName() is causing the issue. See below.

var a = document.getElementsByClassName("cc");
for (var i = 0; i < a.length; i++) {
  console.log(`----- Loop ${i} -----`);
  // Current HTML collection
  console.log(a);
  // Target element
  console.log(`Target: ${a[i].textContent}`);
  a[i].className = "cd"; 
}
<ul>
  <li class="cc">A</li>
  <li class="cc">B</li>
  <li class="cc">C</li>
  <li class="cd">D</li>
</ul>

How your for loop works:

  1. a = [A, B ,C]
  2. a[0] = A -> A.className = 'cd'
  3. a = [B, C]
  4. a[1] = C -> C.className = 'cd'
  5. a = [B]
  6. a[2] = undefined -> loop ends

Solution

Use .querySelectorAll() instead of .getElementsByClassName(). The former yields a static collection and the latter is dynamic (meaning that as you update the DOM, the collection itself is updated as well).

var a = document.querySelectorAll(".cc");
for (var i = 0; i < a.length; i++) {
  a[i].className = "cd";
}
.cc {
  background-color: blue;
}

.cd {
  background-color: chartreuse;
}
<ul>
  <li class="cc">A</li>
  <li class="cc">B</li>
  <li class="cc">C</li>
  <li class="cd">D</li>
</ul>

Modern solution

Use .forEach() instead of for loop.

const a = document.querySelectorAll('.cc');
a.forEach(element => element.className = 'cd');
.cc {
  background-color: blue;
}

.cd {
  background-color: chartreuse;
}
<ul>
  <li class="cc">A</li>
  <li class="cc">B</li>
  <li class="cc">C</li>
  <li class="cd">D</li>
</ul>
like image 93
Miu Avatar answered Oct 04 '22 20:10

Miu