Estoy haciendo un todolist en este momento y encontré un problema al eliminar una lista.
// nest icon inside button tag
delBtn.innerHTML = '<i class="fas fa-times fa-lg"></i>';
He anidado un icono dentro de una etiqueta de botón, por lo que cuando hago clic en el botón Eliminar en el borde, elimina la etiqueta ul. Y al hacer clic dentro de la etiqueta del botón, se elimina una lista a lo que estoy apuntando exactamente.
Entonces ... ¿Cómo tengo que solucionar este problema para eliminar solo el que quiero? Siempre que hago clic en el borde del botón, se elimina toda la lista.
function addTodo(todo) {
let todoText = todoInput.value; // new input
if (todo) {
// existing todo loaded from LS
todoText = todo.text;
}
if (todoText) {
const todoLI = document.createElement('li');
const delBtn = document.createElement('button');
const text = document.createElement('span');
// nest icon inside button tag
delBtn.innerHTML = '<i class="fas fa-times fa-lg"></i>';
// DELETE: event
delBtn.addEventListener('click', (e) => {
e.target.parentNode.parentNode.remove();
updateLS();
});
text.innerText = todoText;
todoLI.appendChild(delBtn);
todoLI.appendChild(text);
todoUL.appendChild(todoLI);
todoInput.value = '';
updateLS();
}
2 respuestas
Tu problema es que target
puntos al elemento más profundo del DOM que recibió el evento ( click
aquí ). Entonces, si hace clic en i
, apuntará a eso, pero si hace clic en el botón, pero fuera de i
, apuntará al elemento button
.
Entonces, el .parentNode.parentNode
será diferente, dependiendo de dónde haga clic.
Utilice currentTarget
en lugar de target
que apunta al elemento con el controlador de eventos para que tenga un punto de inicio normalizado ( el button
en este caso ).
delBtn.addEventListener('click', (e) => {
e.currentTarget.parentNode.remove();
updateLS();
});
Otro enfoque, dado que ya tiene una referencia al elemento li
para eliminar, solo use ese
delBtn.addEventListener('click', (e) => {
todoLI.remove();
updateLS();
});
Aquí se explica cómo delegar para el botón
Utilizo el botón más cercano para permitir hacer clic en el icono dentro del botón. Entonces uso el LI más cercano para llegar siempre al LI que lo contiene
No manejé la actualización o el almacenamiento de la lista.
const updateLS = () => {}
function addTodo(e) {
e.preventDefault(); // stop form
let todoText = todoInput.value; // new input
// existing todo loaded from LS
// const todo = getTodo() || []; // get from localStorage
const todo = [];
if (todoText) {
const todoLI = document.createElement('li');
const delBtn = document.createElement('button');
const text = document.createElement('span');
// nest icon inside button tag
delBtn.innerHTML = '<i class="fas fa-times fa-lg"></i>';
text.innerText = todoText;
todoLI.appendChild(delBtn);
todoLI.appendChild(text);
todoUL.appendChild(todoLI);
todoInput.value = '';
updateLS();
}
}
const form = document.getElementById("todoForm");
form.addEventListener("submit",addTodo)
form.addEventListener("click",function(e) {
const tgt = e.target.closest("button"); // make sure we access the button
if (tgt) {
tgt.closest("li").remove(); // the container LI
updateLS();
}
});
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css" />
<form id="todoForm">
<input type="text" id="todoInput" autocomplete="off" />
<ul id="todoUL"></ul>
</form>
Preguntas relacionadas
Nuevas preguntas
javascript
Para preguntas sobre la programación en ECMAScript (JavaScript / JS) y sus diversos dialectos / implementaciones (excepto ActionScript). Incluya todas las etiquetas relevantes en su pregunta; por ejemplo, [node.js], [jquery], [json], etc.