Agrega un evento en múltiples elementos con event delegation

En este post hablaremos sobre event delegation, en JavaScript. La solución a tus problemas de performance y escalabilidad en tu proyecto actual, donde tal vez tengas una tabla de usuarios.

Cada usuario tiene los botones de editar o eliminar. Sin embargo, estás haciendo un loop para asignarles un evento click para hacer sus respectivas funciones.

Esto soluciona tu requerimiento, pero, si tienes más de 1000 usuarios en esa tabla, ¿será bueno en performance? y mejor aún, ¿será escalable?

¿Qué es event delegation?

El event delegation es un patrón en JavaScript que sugiere registrar un evento, por ejemplo, click, en nuestro document para interceptar todas las interacciones de nuestro documento.

Es decir, si haces click en un botón, lo estás escuchando, y si haces click fuera del botón, también lo estás escuchando.

¿Suena ilógico no? ¿Por qué queremos escuchar todos los clicks de todo nuestro sitio web si solo podemos asignarle el evento a los elementos a través de un loop?

Lo mismo pensé cuando escuché sobre esto la primera vez, pero cuando piensas en el performance y escalabilidad, empieza a cobrar sentido.

¿Cómo funciona event delegation?

El truco está en que dentro de la función callback de nuestro evento, hay que usar el objeto event.target.

document.addEventListener('click', () => {
   const clickedElement = event.target;
});

En nuestro ejemplo, event.target es equivalente al elemento que hemos hecho click, el botón, en este caso.

Por otra parte, si haces click afuera del botón, el evento también se ejecutará. Es ahí donde tienes que agregar las condiciones necesarias para que el evento solo responda a los botones y no a todo el contenido del sitio.

See the Pen Agrega un evento JavaScript en múltiples elementos (Event Delegation) by Roel Magdaleno (@roelmagdaleno) on CodePen.

Funciones como matches() o closest() se usan mucho cuando se está trabajando con event delegation.

Antes de event delegation, se usaba un loop

Retomemos el ejemplo del primer párrafo. Tenemos la tabla de 1000 usuarios, y cada uno de ellos tiene un botón para editar; digamos que al hacer click a ese botón, se abre un modal con los datos del usuario para editar.

Lo que yo solía hacer para abrir ese modal, es agregar un evento click a cada uno de los botones con la siguiente lógica:

  1. Obtener los botones.
  2. Pasar por un loop los botones.
  3. Asignar un evento a cada uno de los botones pasados en el loop.

Observa el siguiente demo. Utilizo un forEach para hacer un loop de los elementos y asignarles el evento; también puedes usar for y for ... in. La funcionalidad es la misma.

See the Pen Agrega un evento JavaScript en múltiples elementos (Método 1 - Forma Incorrecta) by Roel Magdaleno (@roelmagdaleno) on CodePen.

Si bien el código anterior funciona. ¿Qué es lo que lo hace incorrecto?

Problema #1: Performance

El performance es algo que debes incluir en tus desarrollos web. Es muy medido por Google y sus Core Web Vitals, además, un buen performance asegura una mejor experiencia para el usuario.

Si tenemos 1000 usuarios y por cada uno podría haber dos botones, editar y eliminar, eso hace que nuestro sistema tenga 2 mil botones en total. Imagina agregar otro botón más.

Ahora, con nuestro sistema actual tendría que hacer loop y agregar los eventos a esos 2 mil botones; y eso, no es para nada saludable para el sitio y navegador web. ¿Diría que incluso podría saturar el navegador?

Otra técnica para un buen performance es ejecutar tu código solo en donde sea necesario.

Problema #2: Escalabilidad

Tu cliente quiere agregar usuarios en esa misma tabla usando AJAX. Se puede, sí; sin embargo, ¿nuestros botones de editar funcionarán después de agregar al usuario?

Seguramente no funcionará porque, previamente, has agregado los eventos a los botones existentes, no a los nuevos.

Uno piensa, ¡ah! pues después de crear el usuario, busco los nuevos botones y les asigno el evento. Si y no. Esto solo genera complejidad y duplicidad de código. No es escalable.

Conclusión

Debemos acostumbrarnos al uso del event delegation, pero siempre analiza si este tipo de patrón es el adecuado para los requerimientos de tu proyecto.

Ya no podemos usar las viejas formas en las que programábamos con JavaScript. Tenemos que actualizar nuestro código para hacer el uso de la web más satisfactoria para los usuarios.

Roel Magdaleno
Escrito por Roel Magdaleno

Roel Magdaleno es un ingeniero informático especializado en desarrollo web desde hace más de 5 años. Desarrolla sitios web, aplicaciones web, plugins para WordPress y scripts con PHP y JavaScript. Además, comparte su conocimiento en su blog personal.

Deja un comentario