Saltar la navegación

3.4.- Orden de disparo de los eventos.

Imagina que tenemos un elemento contenido dentro de otro elemento, y que tenemos programado el mismo tipo de evento para los dos (por ejemplo el evento click). ¿Cuál de ellos se disparará primero? Sorprendentemente, ésto va a depender del tipo de navegador que tengamos.

El problema es muy simple. Imagina que tenemos el siguiente gráfico:

Gráfico con un una jerarquía de dos elementos.

y ambos tienen programado el evento de click. Si el usuario hace click en el elemento2, provocará un click en ambos: elemento1 y elemento2. ¿Pero cuál de ellos se disparará primero?, ¿cuál es el orden de los eventos?

Modelo W3C

W3C decidió que, cuando se produce un evento en su modelo de eventos, primero se producirá la fase de captura hasta llegar al elemento de destino, y luego se producirá la fase de burbujeo hacia arriba. Este modelo es el estándar, que todos los navegadores deberían seguir para ser compatibles entre sí.

Tú podrás decidir cuando quieres que se registre el evento: en la fase de captura o en la fase de burbujeo. El tercer parámetro de addEventListener te permitirá indicar si lo haces en la fase de captura (true), o en la fase de burbujeo (false).

Por ejemplo:

elemento1.addEventListener('click', hacerAlgo1 ,true);
elemento2.addEventListener('click', hacerAlgo2, false);

Diagrama con el orden de burbujeo de los eventos entre elementos.Si el usuario hace click en el elemento2 ocurrirá lo siguiente:

  1. El evento de click comenzará en la fase de captura. El evento comprueba si hay algún ancestro del elemento2 que tenga un evento de onclick para la fase de captura (true).
  2. El evento encuentra un elemento1.hacerAlgo1() que ejecutará primero, pues está programado a true.
  3. El evento viajará hacia el destino, pero no encontrará más eventos para la fase de captura. Entonces el evento pasa a la fase de burbujeo, y ejecuta hacerAlgo2(), el cuál hemos registrado para la fase de burbujeo (false).
  4. El evento viaja hacia arriba de nuevo y chequea si algún ancestro tiene programado un evento para la fase de burbujeo. Éste no será el caso, por lo que no hará nada más.

Para detener la propagación del evento en la fase de burbujeo, disponemos del método stopPropagation(). En la fase de captura es imposible detener la propagación.