Uninstallme

Event bubbling y event capturing son dos conceptos de javascript relativos al orden en que las funciones asociadas a un mismo tipo de evento deben ejecutarse.  Aunque es posible que en la práctica este comportamiento de los eventos no suponga un problema, hay que saber que el burbujeo o event bubbling siempre ocurre y hay que tenerlo en cuenta en eventos de tipo mouseover, mousemove, mouseout, etc.

Para comprenderlo mejor, no hay nada como mostrar ejemplos de cada uno de ellos.

Si hemos asociado una función para un tipo de evento, por ejemplo onclick, en un elemento padre y otra función para el mismo tipo de evento en un elemento hijo, cuando el evento tenga lugar en el elemento hijo, se ejecutará también la función para el elemento padre. Esto es lo que se conoce como event bubbling y es el comportamiento por defecto de los eventos cuando son registrados en el modo tradicional (elemento.onclick = function())

Ejemplo de event bubbling

El bloque verde (elemento hijo) está dentro del bloque amarillo (elemento padre). Al hacer click en el bloque amarillo se debe mostrar el mensaje de alerta “Hola mundo” y al hacer click en el bloque verde se debe mostrar el mensaje “Hello world”. Si hacemos click en el bloque verde, veremos ejecutarse las dos funciones, primero la del bloque verde y después la del bloque amarillo.

Elemento padre

Click para ver “Hola mundo”

Elemento hijo

Click para ver “Hello world”

Diferencias entre navegadores

Como suele ser habitual, Microsoft y Netscape apostaron por distintos modelos:

  • Netscape said that the event on element1 takes place first. This is called event capturing
  • Microsoft maintained that the event on element2 takes precedence. This is called event bubbling

Mientras que navegadores basados en Gecko, Opera y Konkeror soportan los dos modelos, bubbling y capturing, Explorer sólo soporta el primero. Versiones antiguas de Opera no soportan ninguno de los dos.

El método addEventListener() del DOM, permite especificar qué comportamiento (bubbling o capturing) se establecerá para un manejador de evento dependiendo del valor (true o false) de su último argumento. En el siguiente ejemplo se establece en el modelo de captura mediante el valor true.

Ejemplo de event capturing (no soportado por Internet Explorer)

Elemento padre

Click para ver “Hola mundo”

Elemento hijo

Click para ver “Hello world”

Internet Explorer tiene su propio modelo de registro de eventos y no soporta el método estándar del DOM addEventListener(). En su lugar utiliza el método attachEvent() con importantes limitaciones e inconvenientes:

  • No es posible hacer uso de event capturing.
  • La palabra reservada this siempre hace referencia al objeto window.

Recomiendo echarle un vistazo al addEvent de Dean Edwards que soluciona el problema mencionado con this en Explorer.

Evitar la propagación

El método estándar del DOM stopPropagation(), sirve para evitar el burbujeo o event bubbling. Internet Explorer necesita del uso de la propiedad no estándar* cancelBubble del objeto event.

Para cancelar la propagación de un evento podemos usar la siguiente función:


function cancelBubbling(e){
	if(!e) e = window.event;
	e.cancelBubble = true;
	if(e.stopPropagation) e.stopPropagation();
}

En este ejemplo se utiliza la función anterior para detener la propagación y se añade otra pequeña función cross-browser para evitar que se ejecute la acción por defecto en un elemento html (seguir destino del enlace en elemento <a>)


function cancelDefault(e){
	if(!e) e = window.event;
	e.returnValue = false;
	if(e.preventDefault) e.preventDefault();
}

Elemento padre

Click para ver “Hola mundo”

Fuentes y más información

* cancelBubble es una propiedad del objeto event definida por el DOM: http://www.w3.org/TR/1999/WD-DOM-Level-2-19990304/events.html

Deja tu comentario

Los campos marcados con (*) son obligatorios