Estoy tratando de hacer una especie de lista de tareas pendientes. Cuando hago clic en el botón Guardar, crea un nuevo li con el valor de entrada, y crea otro li de ul con un botón de eliminación. Lo que quiero ahora es hacer clic en el botón Eliminar y eliminar ese li. Por alguna razón, solo el primer botón lo elimina, y elimina cada li del primero al último.
Este es el html:
<input type="text" id="itemname"> <button id="save">Salvar</button> <main id="lists"> <ul id="itemlist"></ul> <ul id="listbutton"></ul> </main>Y aquí está el js:
let list = document.getElementById("itemlist") let buttonList = document.getElementById("listbutton") let listItem = document.getElementById("itemname") let button = document.getElementById("save") button.onclick = saveItem function removeitem(){ let newli = document.querySelector("#itemlist li") list.removeChild(newli) } function saveItem(){ list.innerHTML += '<li>'+listItem.value+'</li>' buttonList.innerHTML += '<li id="newitem"><button id="removebutton">Remover</button></li>' let delBtn = document.querySelector("#listbutton button") delBtn.onclick = removeitem }Es posible que desee utilizar Event.target en su detector de eventos:
function removeitem(event){ let newli = event.target.closest('li'); list.removeChild(newli); } Editar: Además, solo está adjuntando el detector de eventos a un elemento, porque querySelector solo devuelve la primera coincidencia. Para adjuntar el detector de eventos a todos los elementos, debe iterar:
let delBtns = document.querySelectorAll("#listbutton button"); [...delBtns].forEach(el=> el.onclick = removeitem);O, alternativamente, necesitaría adjuntar un solo detector de eventos a un elemento superior, lo que aprovecharía el burbujeo de eventos:
let parentElement = document.querySelector("#listbutton") parentElement.onclick = removeitem; Esto es usar Element.closest como la solución más robusta/estable, pero en su ejemplo, dado que el botón es un elemento secundario directo de la etiqueta li , también podría adoptar el enfoque más simple y usar event.target.parentElement . Pero si cambiara la estructura DOM en el futuro, esto podría romperse.
Prueba esto, he hecho algunos pequeños ajustes para que sea un poco más suave.
// Create a "close" button and append it to each list item var myNodelist = document.getElementsByTagName("LI"); var i; for (i = 0; i < myNodelist.length; i++) { var span = document.createElement("SPAN"); var txt = document.createTextNode("\u00D7"); span.className = "close"; span.appendChild(txt); myNodelist[i].appendChild(span); } // Click on a close button to hide the current list item var close = document.getElementsByClassName("close"); var i; for (i = 0; i < close.length; i++) { close[i].onclick = function () { var div = this.parentElement; div.style.display = "none"; } } // Add a "checked" symbol when clicking on a list item var list = document.querySelector('ul'); list.addEventListener('click', function (ev) { if (ev.target.tagName === 'LI') { ev.target.classList.toggle('checked'); } }, false); // Create a new list item when clicking on the "Add" button function newElement() { var li = document.createElement("li"); var inputValue = document.getElementById("myInput").value; var t = document.createTextNode(inputValue); li.appendChild(t); if (inputValue === '') { alert("You must write something!"); } else { document.getElementById("myUL").appendChild(li); } document.getElementById("myInput").value = ""; var span = document.createElement("SPAN"); var txt = document.createTextNode("\u00D7"); // x for remove item span.className = "close"; span.appendChild(txt); li.appendChild(span); for (i = 0; i < close.length; i++) { close[i].onclick = function () { var div = this.parentElement; div.style.display = "none"; } } } <input type="text" id="myInput" placeholder="Title..."> <button onclick="newElement()" class="addBtn">Salvar</button> <main id="lists"> <ul id="myUL"></ul> </main>