Accede a todo EDteam con un único pago¡Sube a premium con -50%!

¿Cómo usar la delegación de eventos en JavaScript?

Hola amigos, seguro ya saben que cuando queremos escuchar eventos en JavaScript (por ejemplo, cuando se hace click en un botón), la sintaxis es la siguiente:

Diseño web
4 minutos
Hace 7 años
¿Cómo usar la delegación de eventos en JavaScript?

Hola amigos, seguro ya saben que cuando queremos escuchar eventos en JavaScript (por ejemplo, cuando se hace click en un botón), la sintaxis es la siguiente:

1// vanilla 2el.addEventListener('eventType', () => 3 // eventHandler 4); 5 6// jQuery 7$('elSelector').on('eventType', () => 8 // eventHandler 9);

Donde eventType es un tipo de evento (https://developer.mozilla.org/en-US/docs/Web/Events) y el eventHandler es la función que se ejecutará cuando el eventType se dispare.

Hasta ahi, perfecto. Sin embargo, si queremos que varios elementos escuchen el mismo eventType y ejecuten el mismo eventHandler (por ejemplo, en una galería de fotos poder hacer clic en cualquiera de las miniaturas para mostrar la versión ampliada), nuestro primer razonamiento sería iterar sobre ellos.

1var galleryImg = document.querySelectorAll('.gallery-item'); 2 3for(let i = 0; i < galleryImg.length; i++) { 4 galleryImg[i].addEventListener('eventType', () => 5 // eventHandler 6 ) 7}

Si usamos jQuery, es más sencillo aún, pues hace la iteración por nosotros.

1$('.gallery-item').on('eventType', () => 2 // eventHandler 3)

Sin embargo, el principal problema con estos enfoques es que solo aplica a los elementos existentes en el DOM al cargar la página. Con lo cual, si añadimos elementos dinámicamente, estos no se verán afectados por el evento. Por otro lado, si evitamos la iteración, podemos ganar rendimiento. Para eso utilizamos la Delegación de eventos que consiste en escuchar el evento en el elemento padre solamente para luego capturarlo cuando ocurra en sus hijos. Esto gracias a un comportamiento de los eventos llamado Bubbling.

Bubbling

El bubbling (burbujeo) es una fase de los eventos (la otra es capturing y ambos dan para un próximo post en más detalle) que significa que cuando un evento ocurre en el DOM, es capturado en el elemento HTML más profundo posible, y de ahi se va elevando hacia sus padres en orden de jerarquía hasta llegar al objeto global (window). Por lo tanto, cuando un evento ocurre en un elemento, también está ocurriendo en sus padres.

Delegación de eventos

Ahora que sabemos que si un evento ocurre  en un hijo, también está ocurriendo en sus padres. Volvamos al ejemplo de la galería. Ahora no necesitamos iterar sobre los elementos, sino escuchar el evento en el padre. 

Tomemos en cuenta el siguiente HTML

1<div class="gallery-container"> 2 <a href="" class="gallery-item"><img src="" alt=""></a> 3 <a href="" class="gallery-item"><img src="" alt=""></a> 4 <a href="" class="gallery-item"><img src="" alt=""></a> 5 <a href="" class="gallery-item"><img src="" alt=""></a> 6 <a href="" class="gallery-item"><img src="" alt=""></a> 7 <a href="" class="gallery-item"><img src="" alt=""></a> 8 <a href="" class="gallery-item"><img src="" alt=""></a> 9 <a href="" class="gallery-item"><img src="" alt=""></a> 10 <a href="" class="gallery-item"><img src="" alt=""></a> 11</div>

Tenemos nueve elementos gallery-item. Pero podrían ser más. Sin embargo, como ya conocemos la delegación, escucharemos el evento una sola vez en el padre. Recuerda que podemos pasar el objeto Eventcomo parámetro (lo nombraremos e en nuestros ejemplos), al event Handler para asi obtener el target que es el elemento que dispara el evento.

1let gallery = document.querySelector('.gallery-item'); 2 3gallery.addEventListener('eventType', e => 4 console.log(e.target) // nos imprime en consola el elemento que dispara el evento 5); 6

Y como en nuestro caso queremos capturar el evento en todos los elementos con la clase gallery-item, lo haremos así:

1// vanilla 2let gallery = document.querySelector('gallery-container'); 3gallery.addEventListener('eventType', e => { 4 if(e.target.classList.contains('gallery-item')){ 5 // bla bla bla 6 } 7}); 8 9// jQuery 10$('.gallery-container').on('eventType', '.gallery-item', () => 11 // bla bla bla 12);

Sobre ES6 y this

En este articulo estamos usando ES6 (si no lo estás usando, deberías). Ten en cuenta que si usas una arrow function para el eventHandler no podrás capturar el elemento que dispara el evento usando this (como en ES5) por eso se recomienda usar e.target

Cuéntanos si te sirvió este artículo o si hay algo que se nos escapó mencionar.

Hasta la próxima.

Comentarios de los usuarios

Pregunta a ChatEDT