Pasar al contenido principal

🔥 Hoy comenzamos la especialidad en programación backend con PHP con Yesi Days ¡La primera clase es en vivo y gratis! 😍 Reserva tu lugar. Comienza en:

Alexys Lozada
José Luján
Manuel Rodriguez
José Luján
Luis Avilés
Álvaro Felipe
José Luján
Beto Quiroga
Jonathan MirCha
Jonathan MirCha
Álvaro Felipe
Alexys Lozada, Álvaro Felipe, Jonathan MirCha
Beto Quiroga
Alexys Lozada
Alexys Lozada
José Luján
Álvaro Felipe
Álvaro Felipe
Jonathan MirCha
Jonathan MirCha
Alexys Lozada, José Luján
Alexys Lozada, José Luján
Alexys Lozada, José Luján
Camilo Adobe
Álvaro Felipe
José Luján
Jonathan MirCha
Álvaro Felipe
Álvaro Felipe
Beto Quiroga, Alexys Lozada
Álvaro Felipe
Juan Villalvazo
Luis Avilés
Jonathan MirCha
Jonathan MirCha
Jonathan MirCha

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

¿Cómo usar la delegación de eventos en JavaScript? - Blog de Escuela Digital

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:

// vanilla
el.addEventListener('eventType', () =>
  // eventHandler
);

// jQuery
$('elSelector').on('eventType', () =>
  // eventHandler
);

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.

var galleryImg = document.querySelectorAll('.gallery-item');

for(let i = 0; i < galleryImg.length; i++) {
  galleryImg[i].addEventListener('eventType', () =>
    // eventHandler
  )
}

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

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

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

<div class="gallery-container">
  <a href="" class="gallery-item"><img src="" alt=""></a>
  <a href="" class="gallery-item"><img src="" alt=""></a>
  <a href="" class="gallery-item"><img src="" alt=""></a>
  <a href="" class="gallery-item"><img src="" alt=""></a>
  <a href="" class="gallery-item"><img src="" alt=""></a>
  <a href="" class="gallery-item"><img src="" alt=""></a>
  <a href="" class="gallery-item"><img src="" alt=""></a>
  <a href="" class="gallery-item"><img src="" alt=""></a>
  <a href="" class="gallery-item"><img src="" alt=""></a>
</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 Event como parámetro (lo nombraremos e en nuestros ejemplos), al event Handler para asi obtener el target que es el elemento que dispara el evento.

let gallery = document.querySelector('.gallery-item');

gallery.addEventListener('eventType', e => 
  console.log(e.target) // nos imprime en consola el elemento que dispara el evento
);

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

// vanilla
let gallery = document.querySelector('gallery-container');
gallery.addEventListener('eventType', e => {
  if(e.target.classList.contains('gallery-item')){
    // bla bla bla
  }
});

// jQuery
$('.gallery-container').on('eventType', '.gallery-item', () =>
  // bla bla bla
);

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.

Suscríbete al blog de EDteam

Ingresa tu correo electrónico para recibir nuestro boletín semanal