Estoy tratando de aprender Javascript creando esta aplicación de tareas muy simple. Puedo escribir algún valor en la entrada. Cuando se presiona el botón Intro o Enviar, el valor de la etiqueta de entrada se agrega a la UL como una lista. Luego se agrega una clase 'elemento de lista' a esa etiqueta li.
Mi problema es: quiero cruzar cualquier lista individual cuando se hace clic. He usado el siguiente código para eso. Tengo el estilo 'cruz' en mi CSS, pero el problema es que mi código no cruza todas las listas individuales. Cruza todos los demás. Probé forEach también y el resultado es el mismo.
const listItems = document.querySelectorAll('list-item'); for (let i=0; i<listItems.length; i++) { listItems[i].addEventListener('click', function() { console.log(listItems[i]) listItems[i].classList.toggle('cross'); }) }todo mi javascript:
const input = document.getElementById('main-input') const submit = document.getElementById('submit') const ul = document.getElementById('to_dos'); const del = document.getElementById('del') //clicking submit button submit.addEventListener('click', function() { addList() }) //pressing enter key input.addEventListener("keypress", function(event) { if(event.keyCode === 13) { event.preventDefault() addList() } }) //add new todo in the list from input const addList = () => { const newToDo = document.createElement('LI') newToDo.classList.add('list-item') newToDo.appendChild(document.createTextNode(input.value)) ul.appendChild(newToDo) input.value = "" //cross the completed tasks const listItems = document.querySelectorAll('li.list-item'); for (let i=0; i<listItems.length; i++) { listItems[i].addEventListener('click', function() { console.log(listItems[i]) listItems[i].classList.toggle('cross'); }) } //delete button del.addEventListener('click', function() { const completedItems = document.querySelectorAll('.cross'); completedItems.forEach( completedItem => { completedItem.classList.add('hide') } ) }) }En su codepen, está asignando incorrectamente el detector de clics. En lugar de adjuntar un oyente a cada elemento agregado individualmente, recorre TODOS los elementos CADA vez que se agrega uno nuevo, y cuando combina oyentes de eventos como ese, puede tener resultados no deseados.
En su función addList , en lugar de recorrer todas las entradas con esto:
//cross the completed tasks const listItems = document.querySelectorAll('li'); listItems.forEach(listItem => listItem.addEventListener('click', e => { e.target.classList.toggle('cross'); }))Simplemente adjunte el oyente al nuevo agregado:
newToDo.addEventListener('click', e => { e.target.classList.toggle('cross'); })simplemente olvida agregar un punto (.) al comienzo del método querySelectorAll . en su caso, le dijo al método querySelectorAll que busque todas las etiquetas de elementos de lista para que ese punto cambie el significado para encontrar todas las clases de elementos de lista . y querySelectorAll devolverá HTMLCollection no Array , por lo que el método forEach no funcionará, debe devolverlo a Array usando la función Array() o de la siguiente manera.
[...document.querySelectorAll('.list-item')] .forEach(function(element){ element.addEventListener("click", function(){ element.classList.toggle("cross") }) })