javascriptaddeventlistener

addEventListener on a querySelectorAll() with classList


I am trying to add an event listener but no result came. I know JavaScript has a hoisting feature but I believe I tried all except the correct solution.

const cbox = document.querySelectorAll(".box");
function doit() {
  for (let i = 0; i < cbox.length; i++){
    cbox[i].classList.add("red");
  }
}
cbox.addEventListener("click", doit, false);

Can somebody spot the mistake I make?


Solution

  • There are some dissimilarities between the code and the link you have provided. There is no function doit() in there.

    You have attached addEvenListener to the NodeList in cbox.addEventListener("click",....., you have to loop through the list and attach the event to the current element:

    Try the following:

    const cbox = document.querySelectorAll(".box");
    
     for (let i = 0; i < cbox.length; i++) {
         cbox[i].addEventListener("click", function() {
           cbox[i].classList.toggle("red");
         });
     }
    *,
    html,
    body {
        padding: 0;
        margin: 0;
    }
    
    .box {
        width: 10rem;
        height: 10rem;
        background-color: yellowgreen;
        float: left;
        position: relative;
        margin: 0.5rem;
        transition: .5s all;
    }
    
    h3 {
        display: block;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }
    
    .box:not(:first-child) {
        margin-left: 1rem;
    }
    
    .red {
        background-color: orangered;
    }
    <div id="box1" class="box box1">
        <h3>Box 1</h3>
    </div>
    <div id="box2" class="box box2">
        <h3>Box 2</h3>
    </div>
    <div id="box3" class="box box3">
        <h3>Box 3</h3>
    </div>
    <div id="box4" class="box box4">
        <h3>Box 4</h3>
    </div>

    You can also use Array.prototype.forEach() with arrow function syntax that will allow you to achieve the same with less code:

    let cbox = document.querySelectorAll(".box");
    cbox.forEach(box => {
      box.addEventListener('click', () => box.classList.toggle("red"));
    });
    *,
    html,
    body {
        padding: 0;
        margin: 0;
    }
    
    .box {
        width: 10rem;
        height: 10rem;
        background-color: yellowgreen;
        float: left;
        position: relative;
        margin: 0.5rem;
        transition: .5s all;
    }
    
    h3 {
        display: block;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }
    
    .box:not(:first-child) {
        margin-left: 1rem;
    }
    
    .red {
        background-color: orangered;
    }
    <div id="box1" class="box box1">
        <h3>Box 1</h3>
    </div>
    <div id="box2" class="box box2">
        <h3>Box 2</h3>
    </div>
    <div id="box3" class="box box3">
        <h3>Box 3</h3>
    </div>
    <div id="box4" class="box box4">
        <h3>Box 4</h3>
    </div>