Home > Mobile >  How come my 'click' eventListener works for the first 2 <li>'s and not the rest
How come my 'click' eventListener works for the first 2 <li>'s and not the rest

Time:07-05

I am relatively new to programming. I got my 'click' eventListener to work, and when you click on the first two li's in the ul, the class of the div toggles on and off. However, when you click on any li after the second one, it toggles the class of every other div and not the one that is clicked on? If you need more clarification regarding the situation, feel free to let me know.

For example, if the for loop were to print:

  • Bench Press
  • Deadlift
  • Squat
  • Shoulder press
  • Curl

If i click on 'bench press' and 'deadlift' it will toggle .info and show the information for it; but if i were to click on 'squat' it will toggle .info for the 'curl' instead, so on and so forth...

Here is all the code,

<div>
    {% for workout in workouts %}
    <ul>
        <li >{{ workout.name }}</li>

        {% autoescape false %}
        <div  id="info">
            <p>{{ workout.description }}</p>
        </div>
        {% endautoescape %}
    </ul>
    {% endfor %}
</div>
let li = document.querySelectorAll("li");
let info = document.querySelectorAll(".info");

for (let i = 0; i < li.length; i  ) {
  li[i].addEventListener("click", function () {
    info[i].classList.toggle("info");
  });
}
.info {
  display: none;
}

CodePudding user response:

Your javascript code is fine.

Make sure your HTML is valid.

Each html tag has to be properly closed. So ether <tag /> or <tag> </tag>, when the browser encounters what it deems incomplete, it will attempt to patch things up, that could cause your <li> and <div> pairs to misalign.

I saw you've edited your question, so it might not be relevant anymore.

note that you debug and inspect the actual html the browser has interpreted, rightclick-> inspect will open a view where you can see the state of the browser

let li = document.querySelectorAll("li");
let info = document.querySelectorAll(".info");

for (let i = 0; i < li.length; i  ) {
  li[i].addEventListener("click", function() {
    info[i].classList.toggle("info");
  });
}
.info {
  display: none;
}

.info-colour {
  background: chocolate;
}

.item {
  margin-top: 1rem;
  background: orange;
}

p {
  margin: 0
}
<div>

  <ul>
    <li > workout.name 1</li>
    <div >
      <p> workout.description 1 </p>
      <div>
        Necessary Workout Equpiment: [Specific Machinery]
      </div>
    </div>


    <li >workout.name 2</li>
    <div >
      <p> workout.description 2 </p>
      <div>
        Necessary Workout Equpiment: [Specific Machinery]
      </div>
    </div>


    <li >workout.name 3</li>
    <div >
      <p> workout.description 3 </p>
      <div>
        Necessary Workout Equpiment: [Specific Machinery]
      </div>
    </div>

  </ul>
</div>

CodePudding user response:

The i variable stores the last value after the loop, since it is in another callback function.

Try this fix:

let li = document.querySelectorAll("li");
for (let i = 0; i < li.length; i  ) {
  let liItem = li[i];
  liItem.addEventListener("click", function () {
    liItem.querySelector("div").classList.toggle("info");
  });
}
  • Related