Search code examples
javascripthtmlgetelementsbyclassname

getElementsByClassName strange behavior, skipping certain elements


I am having some very strange behavior with getElementsByClassName, and I am not sure what is causing it.

If I try to swap all elements from class B to class A, it only swaps certain elements as seen below:

function swapClasses() {
    // Get all elements of class B
    const classBList = document.getElementsByClassName("classb");
    for (var i = 0; i < classBList.length; i++) {
        var classElem = classBList[i];
        // Swap its class from class B to class A
        classElem.className = "classa";
        // Swap the text as well
        classElem.textContent = "Class A";
    }
}
.classa {
    background-color: red;
}

.classb {
    background-color: green;
}
<div class="classa">Class A</div>
<div class="classb">Class B</div>
<div class="classb">Class B</div>
<div class="classb">Class B</div>
<div class="classb">Class B</div>
<button onclick="swapClasses();">Swap class B to class A</button>

I have no idea why this happens, and I would love to fix it if possible.

Any help would be appreciated!


Solution

  • You can use querySelectorAll and classList instead of the live nodelist you get with getElementsByClassName

    function swapClasses() {
      // Get all elements of class B
      document.querySelectorAll(".classb").forEach(div => {
        div.classList.add("classa");
        div.classList.remove("classb");
        // Swap the text as well
        div.textContent = "Class A";
      })
    }
    .classa {
      background-color: red;
    }
    
    .classb {
      background-color: green;
    }
    <div class="classa">Class A</div>
    <div class="classb">Class B</div>
    <div class="classb">Class B</div>
    <div class="classb">Class B</div>
    <div class="classb">Class B</div>
    <button onclick="swapClasses();">Swap class B to class A</button>

    Use [...document.querySelectorAll(".classb")].forEach

    if you want to support older Edge