0
<!DOCTYPE html>
    <html>
    <head>
        <title>To-Do</title>
    <link rel="stylesheet" type="text/css" href="todos.css">
    </head>
    <body>
    <ul>
        <li><span>X</span> Do Programming</li>
        <li><span>X</span> Do More Programming</li>
        <li><span>X</span> Do more and more Programming</li>
    </ul>
    <script type="text/javascript" src="todos.js"></script>
    </body>
    </html>

css

.toggleli {
text-decoration: line-through;
color: grey;

}

Javascript

var li = document.querySelectorAll("li");

for(i=0; i < li.length; i++) {
li[i].addEventListener("click", function() { 
    li[i].classList.toggle("toggleli");
});
}

This is the error

todos.js:5 Uncaught TypeError: Cannot read property 'classList' of undefined
    at HTMLLIElement.<anonymous>

But when i change the li[i].classList.toggle("toggleli"); to this.classList.toggle("toggleli"); the error goes away. Whats the problem with li[i].classList and li.classList inside the for loop because outside that for loop it doesn't show the error but i have to toggle all the li's so i have to put it inside the loop

Jolten
  • 1
  • 1
  • Because all of your `li` elements are getting an event handler that each rely on the `i` variable from your loop, each event handler shares the same, one varaible `i` and, by the time you click on any of them, the loop has terminated with a final value for `i` that is one higher than the highest index in your collection returned by `.querySelectorAll()`. You have a "closure" around the `i` variable. If you can avoid the shared `i` variable, the issue won't happen. That can be done in a variety of ways, but the simplest is to just write `this.classList...` – Scott Marcus Mar 08 '18 at 07:34
  • Thank you for the explanation. – Jolten Mar 08 '18 at 07:38
  • all things are correct wrap your function within window.onload=function(){var li = document.querySelectorAll("li"); for(i=0; i < li.length; i++) { li[i].addEventListener("click", function() { li[i].classList.toggle("toggleli"); }); } } – Negi Rox Mar 08 '18 at 11:32
  • this error will comoe usually when your script is executed first instead of DOM . to make sure DOM is loading please use windo.onload. or document.readyfunction of jquery – Negi Rox Mar 08 '18 at 11:33

1 Answers1

0

Use this instead of li[i] in click event

var li = document.querySelectorAll("li");

for (i = 0; i < li.length; i++) {
  li[i].addEventListener("click", function() {
    this.classList.toggle("toggleli");
  });
}
.toggleli {
  text-decoration: line-through;
  color: grey;
}
<ul>
  <li><span>X</span> Do Programming</li>
  <li><span>X</span> Do More Programming</li>
  <li><span>X</span> Do more and more Programming</li>
</ul>
Sanchit Patiyal
  • 4,910
  • 1
  • 14
  • 31