CodeAventura
JavaScript en el DOM
▸Contenido y eventos▸Delegación de eventos

Misión

<!DOCTYPE html>
<html lang="es">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Delegación de eventos</title>
  </head>
  <body>
    <ul id="lista-productos">
      <li><button class="btn-agregar">Agregar teclado</button></li>
      <li><button class="btn-agregar">Agregar mouse</button></li>
      <li><button class="btn-agregar">Agregar monitor</button></li>
    </ul>
    <p id="carrito">Carrito vacío</p>

    <script src="script.js"></script>
  </body>
</html>
●localhost:5173
11 / 16Delegación de eventos
Anterior

Delegación de eventos

El problema de escalar listeners

Imagina que tienes una lista de productos y cada uno tiene un botón "Agregar al carrito". Si añades un listener a cada botón individualmente, tienes varios problemas:

  • mucho código repetido
  • si añades botones dinámicamente (desde JavaScript), los nuevos no tienen listener
  • mayor consumo de memoria con cientos de elementos

La solución es la delegación: pones un solo listener en el contenedor padre.

Por qué funciona: el bubbling

Cuando haces clic en un elemento, el evento no se queda ahí. Burbujea hacia arriba por el árbol DOM: pasa por el padre, luego el abuelo, hasta llegar a document.

Aprovechando ese burbujeo, puedes escuchar en el <ul> y detectar clicks que ocurrieron en sus hijos.

matches: filtrar por selector CSS

matches comprueba si event.target coincide con el selector CSS que le pases.

closest: cuando el click cae en un hijo interno

Si el botón tiene iconos u otros elementos dentro, event.target puede ser el ícono, no el botón. closest sube por el árbol buscando el ancestro más cercano que coincida:

En la práctica, closest es más robusto que matches para casos donde el elemento tiene hijos.

Beneficio clave: funciona con elementos dinámicos

Si añades nuevos botones a la lista después de cargar la página, el listener del padre los captura automáticamente. Eso es algo que los listeners directos sobre cada elemento no pueden hacer.

Regla práctica

  • Delega en el padre más cercano y estable que contenga los elementos
  • No delegues siempre en document por costumbre: es innecesariamente lejano

Tu desafío 🚀

  1. Añade un listener click al <ul>
  2. Usa event.target para detectar clicks relevantes
  3. Filtra con matches o closest
  4. Actualiza el texto de #carrito con el nombre del producto seleccionado

Delegar eventos es pasar de scripts sueltos a arquitectura de interfaz.