Este es probablemente un javascript súper básico, pero parece que no puedo descifrar cómo cambiar el nombre de clase del li específico en el que estoy haciendo clic.
HTML:
var ul = document.querySelector("ul"); var li = ul.document.querySelectorAll("li"); function loopThroughLi() { for (i = 0; i < li.length; i++) { li[i].addEventListener("click", function() { li[i].classList.toggle("FinishTask"); }) } } loopThroughLi(); .FinishTask { text-decoration: line-through; } <!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body> <ul> <li>Notebook</li> <li>Carrot</li> <li>Spinach</li> <li>Rice</li> </ul> <script type="text/javascript" src="script.js"></script> </body> </html>El problema es que li[i] no está undefined en el momento en que se ejecuta el controlador porque i se ha incrementado hasta li.length para entonces.
Simplemente puede guardar una referencia a li[i] para solucionar el problema.
const ul = document.querySelector("ul"); const li = document.querySelectorAll("li"); function loopThroughLi() { for (let i = 0; i < li.length; i++) { const elem = li[i]; elem.addEventListener("click", function() { elem.classList.toggle("FinishTask"); }); } } loopThroughLi(); .FinishTask{ text-decoration: line-through; } <!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body> <ul> <li>Notebook</li> <li>Carrot</li> <li>Spinach</li> <li>Rice</li> </ul> <script type="text/javascript" src="script.js"></script> </body> </html>la variable i sigue incrementándose hasta que supera la cantidad de elementos en li , por lo que en el momento en que se activa el evento de clic, li[i] no está definido. hay un par de maneras de manejar esto. puede usar this , en lugar de li[i] para alternar la clase. o podría usar let para definir la variable i que cambiará su alcance. o puede guardar li[i] en una variable separada fuera del evento de clic. la primera opción parece la más simple y eficaz.
var ul = document.querySelector("ul"); var li = ul.querySelectorAll("li"); function loopThroughLi() { for (i = 0; i < li.length; i++) { li[i].addEventListener("click", function() { this.classList.toggle("FinishTask"); }) } } loopThroughLi(); .FinishTask { text-decoration: line-through; } <!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body> <ul> <li>Notebook</li> <li>Carrot</li> <li>Spinach</li> <li>Rice</li> </ul> <script type="text/javascript" src="script.js"></script> </body> </html>Cambié para usar una clase para la lista de tareas y una para cada elemento de la tarea, ya que encuentro que el elemento CSS y el script son frágiles de mantener.
Aquí integro la lista de elementos y configuro un controlador de eventos de clic.
También ilustro no solo cómo configurar una clase mediante un conmutador, sino también cómo desactivar la clase en función de un valor de atributo de datos. Hice lo mismo para el atributo de datos e ilustre cómo usarlo en el CSS también, configurando los valores en el ciclo donde agregamos los controladores de eventos a cada uno.
También usé un forEach en cada elemento de la lista de tareas como un conjunto de código más simple, quizás.
const taskList = document.querySelector(".task-list"); const taskItems = taskList.querySelectorAll(".task-item"); function setupItems(items) { items.forEach(function(item, index, items) { //set not done as we initialize item.dataset.isdone = "false"; console.log(index, item); item.addEventListener("click", function(element, index, array) { const alreadyDone = this.dataset.isdone == "true"; this.classList.toggle("finish-task", !alreadyDone); this.dataset.isdone = alreadyDone ? "false" : "true"; }, item); }); } setupItems(taskItems); .finish-task { text-decoration: line-through; } .task-item[data-isdone="true"] { background-color: #ddddff; } .task-item[data-isdone="false"] { background-color: #ddffdd; } <body> <ul class="task-list"> <li class="task-item">Notebook</li> <li class="task-item">Carrot</li> <li class="task-item">Spinach</li> <li class="task-item">Rice</li> </ul> </body>