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:
La solución es la delegación: pones un solo listener en el contenedor padre.
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 CSSmatches comprueba si event.target coincide con el selector CSS que le pases.
closest: cuando el click cae en un hijo internoSi 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.
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.
document por costumbre: es innecesariamente lejanoclick al <ul>event.target para detectar clicks relevantesmatches o closest#carrito con el nombre del producto seleccionadoDelegar eventos es pasar de scripts sueltos a arquitectura de interfaz.