Listas dinámicas con delegación
Gestione eventos de elementos añadidos en tiempo de ejecución.
Listas dinámicas con delegación es una lección gratuita de JavaScript Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de JavaScript Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de JavaScript Academy incluye 4 lecciones en total.
El problema de los elementos dinámicos
Cuando asocia listeners directamente a los elementos, cualquier elemento que se añada al DOM después de la configuración no tendrá ningún listener. La delegación resuelve este problema porque el listener del padre también captura los eventos de los elementos hijos que se añadan posteriormente.
Los listeners directos fallan
Aquí se añade un listener a los elementos existentes. Un elemento añadido posteriormente no recibe nada y queda inactivo.
document.querySelectorAll(".item").forEach((el) =>
el.addEventListener("click", handle)
);
list.appendChild(newItem); // newItem has NO handlerLa delegación funciona sin más
Con un listener delegado en el elemento padre, el nuevo elemento se gestiona automáticamente. No es necesario volver a asociar listeners después de cada inserción.
list.addEventListener("click", (e) => {
const item = e.target.closest(".item");
if (item) console.log("Clicked", item.dataset.id);
});
list.appendChild(newItem); // works immediatelyAñadir elementos
Construya elementos nuevos y añádalos. Como el elemento padre ya delega los eventos, son interactivos desde el momento en que aparecen.
function addItem(text) {
const li = document.createElement("li");
li.className = "item";
li.textContent = text;
list.appendChild(li);
}Eliminar elementos
La eliminación también es sencilla. Un controlador delegado puede detectar un botón de eliminación dentro de la fila y eliminarla.
list.addEventListener("click", (e) => {
if (e.target.matches(".delete-btn")) {
e.target.closest(".item").remove();
}
});Distinguir subacciones
Una fila puede tener varias partes interactivas. Use matches() o closest() para determinar en cuál se hizo clic y, después, tomar una decisión según el resultado.
list.addEventListener("click", (e) => {
if (e.target.matches(".edit-btn")) edit(e);
else if (e.target.matches(".delete-btn")) del(e);
});Renderizar a partir de datos
Un patrón habitual consiste en mantener el estado en un array, renderizar las filas a partir de él y delegar los clics. Volver a renderizar reemplaza los elementos hijos, pero el único listener del padre permanece intacto.
function render(items) {
list.innerHTML = items
.map((i) => "<li class=\"item\" data-id=\"" + i.id + "\">" + i.name + "</li>")
.join("");
}Sin problemas de limpieza
Con listeners por elemento, debe acordarse de llamar a removeEventListener antes de eliminar nodos para evitar fugas de memoria. La delegación elimina esa responsabilidad: al eliminar un elemento hijo no queda ningún listener huérfano.
Alternar clases
La delegación combina bien con la alternancia de clases para los estados de selección. El controlador encuentra la fila y alterna una clase.
list.addEventListener("click", (e) => {
const row = e.target.closest(".item");
if (row) row.classList.toggle("selected");
});Leer una identidad estable
Como los nodos del DOM se reemplazan al volver a renderizar, nunca almacene referencias a ellos. Almacene un id estable en data-id y busque los datos correspondientes por ese id dentro del controlador.
const id = e.target.closest(".item").dataset.id;
const record = state.find((r) => r.id === id);También eventos de entrada
La delegación no se limita a los clics. Puede delegar eventos input o change para campos de formulario añadidos dinámicamente de la misma manera.
form.addEventListener("input", (e) => {
if (e.target.matches(".qty")) recalc(e.target);
});Comprobación rápida
Listas dinámicas y delegación.
Resumen
La delegación resulta especialmente útil con listas dinámicas: un único listener del padre gestiona los elementos hijos actuales y futuros, sobrevive a los nuevos renderizados y no necesita limpieza por nodo. Use matches() y closest() para distinguir subacciones, y almacene ids estables en data-* para que los controladores encuentren su modelo de datos.
Preguntas frecuentes
¿La lección «Listas dinámicas con delegación» es gratis?
Sí — el texto completo de «Listas dinámicas con delegación» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de JavaScript Academy, actualiza a CoddyKit PRO. El curso de JavaScript Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Listas dinámicas con delegación»?
Gestione eventos de elementos añadidos en tiempo de ejecución. Practicas JavaScript Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar JavaScript Academy?
No se requiere experiencia previa. JavaScript Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.
¿Cuánto tiempo toma la lección «Listas dinámicas con delegación»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de JavaScript Academy?
Sí. Cada lección de JavaScript Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Las fases de captura y propagación
- Patrón de delegación de eventos
- Listas dinámicas con delegación
- Eventos personalizados