Javascript y Eventos. Todo lo que necesitas saber

Resumen de cómo funcionan los eventos en Javascript y su propagación por el DOM

¿Qué son los eventos?

Empecemos por lo fundamental. Los eventos os objetos que implementan la interfaz Event definida dentro del estándar del DOM.

¿Cómo se propagan los eventos?

Para entender la forma en que se propagan los eventos atenderemos al siguiente código:

<div id="container">
<div id="dataList">
<div id="clickedData"></div>
</div>
<button id="dataSender">Add new data</button>
</div>
  • callback la función que será invocada cuando se reciba el evento,
  • options es un objeto para modificar el comportamiento por defecto del listener.
const button = document.querySelector('#dataSender');
button.addEventListener('click', function(event) {
console.log('button clicked');
});
  • Bubble, en el cual el evento “sube hacia arriba” como si de una burbuja se tratara.
const body = document.querySelector('body');
const container = document.querySelector('#container');
const button = document.querySelector('#dataSender');
body.addEventListener('click', function(event) {
console.log('body clicked');
});
container.addEventListener('click', function(event) {
console.log('container clicked');
});
button.addEventListener('click', function(event) {
console.log('button clicked');
});
"button clicked""container clicked""body clicked"
button.addEventListener('click', function(event) { 
console.log('button clicked (one)');
}, true);
const button = document.querySelector('#dataSender');
button.addEventListener('click', function(event) {
console.log('button clicked (one)');
});
button.addEventListener('click', function(event) {
console.log('button clicked (two)');
});
const button = document.querySelector('#dataSender');
function onButtonClicked(event) {
console.log('button clicked (one)');
}
button.addEventListener('click', onButtonClicked);
button.removeEventListener('click', onButtonClicked);

¿Y cómo detenemos la propagación?

En el caso de que queramos detener la propagación del evento en algún punto determinado del DOM podremos emplear los métodos event.stopPropagation() o event.stopImmediatePropagation() . Vamos a ver sus diferencias.

stopPropagation()

El método stopPropagation() lo podemos invocar sobre un objeto evento. Para ver su funcionamiento recurriremos al siguiente ejemplo:

const body = document.querySelector('body');
const container = document.querySelector('#container');
const button = document.querySelector('#dataSender');
body.addEventListener('click', function(event) {
console.log('body clicked');
});
container.addEventListener('click', function(event) {
console.log('container clicked');
});
button.addEventListener('click', function(event) {
event.stopPropagation();
console.log('button clicked');
});
button.addEventListener('click', function(event) {
console.log('button clicked (two)');
});

stopImmediatePropagation()

Sin embargo, si queremos prevenir que se ejecuten otros listener asociados al botón podremos emplear el método stopImmediatePropagation de modo que:

const body = document.querySelector('body');
const container = document.querySelector('#container');
const button = document.querySelector('#dataSender');
body.addEventListener('click', function(event) {
console.log('body clicked');
});
container.addEventListener('click', function(event) {
console.log('container clicked');
});
button.addEventListener('click', function(event) {
event.stopImmediatePropagation();
console.log('button clicked');
});
button.addEventListener('click', function(event) {
console.log('button clicked (two)');
});

Oye… ¿Y el famoso preventDefault()?

Cuando trabajamos con eventos en Javascript es muy común ver el siguiente código:

function(event) {
event.preventDefault();
event.stopPropagation();
}
<a id="myLink" href="https://somedomain.invalid">Link</a>
const link = document.querySelector('#myLink');
link.addEventListener('click', function(event) {
event.preventDefault();
// do something cool
});

Lanzando eventos manualmente

Si bien estamos acostumbrados a que sea el navegador quien se encargue de lanzar los eventos según las interacciones de los usuarios, también es posible crear y lanzar eventos manualmente.

event = new CustomEvent(type [, eventInitDict])
const clickedData = document.querySelector('#clickedData');
const anEvent = new CustomEvent('dataSent', {
detail: { foo: 'bar' },
});
clickedData.dispatchEvent(anEvent);
const body = document.querySelector('body');
const container = document.querySelector('#container');
const button = document.querySelector('#dataSender');
const clickedData = document.querySelector('#clickedData');
body.addEventListener('clickedData', function(event) {
console.log('body listener');
});
container.addEventListener('clickedData', function(event) {
console.log('container listener');
});
button.addEventListener('clickedData', function(event) {
console.log('button listener');
});
const anEvent = new CustomEvent('clickedData', {
detail: { foo: 'bar' },
});
clickedData.dispatchEvent(anEvent);
const anEvent = new CustomEvent('clickedData', {
bubbles: true,
detail: { foo: 'bar' },
});
Photo by Zdeněk Macháček on Unsplash

Conclusiones

Como habéis podido ver detrás de la instrucción addEventListener hay bastante lógica detrás que conviene saber por si en algún momento necesitamos crear nuestros propios eventos o profundizar en su uso para determinados caso.

¿Quieres recibir más artículos como este?

Si te ha gustado este artículo te animo a que te suscribas a la newsletter que envío cada domingo con publicaciones similares a esta y más contenido recomendado: 👇👇👇

Entre paseo y paseo con Simba desarrollo en Symfony y React

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store