Hola, tal vez al leer el título de este post parezca o suene medio raro, pero es un tema bastante importante el cual si no se conoce puede causar funcionamientos “extraños” al ejecutar una determinada función jQuery, lo cual podría hacernos pensar que esta mal, cuando realmente no es así, es porque se desconoce como se propagan los eventos.

La propagación de eventos en jQuery describe el flujo de un evento a través de la jerarquía del DOM, cuando un evento es lanzado en un determinado elemento, si existe un manejador para ese evento entonces se ejecuta dicha función, una vez que se ha terminado de procesar el evento es pasado al elemento superior y así sucesivamente.

Esto puede sonar un poco confuso, así que vamos a ilustrarlo, si tenemos algo como:

Se tienen tres divs, uno dentro de otro, y esos divs tienen la clase prop, así entonces definimos el siguiente manejador para el evento clic utilizando jQuery:

1: $("div.prop").click(function () { 2: alert('Ha dado clic en el div: ' + $(this).attr('id')); 3: })

Como selector le decimos que tome todos los div que tengan la clase prop [div.prop], luego que capture el evento click y en el código de la función que por medio de un alert muestre el id del div, esto último accediendo al valor del atributo id.

Y efectivamente cuando damos clic en algún div se muestra el mensaje con el id del control, pero ouch si damos clic en el divNieto luego de mostrar el mensaje con el id divNieto también lo hace para el div hijo y el div padre… es decir nuestro código jQuery no funciona bien ! o mejor aún, no hace lo que lo yo quiero !!

Y efectivamente no hace lo que yo quiero ! Pero no es porque funcione mal… es porque así debe funcionar !!

Ahora bien, porque funciona así? la respuesta esta en el título de este post.. y es porque el evento se propaga !… en otras palabras, cuando se da clic en el divNieto entra al manejador del evento y ejecuta el código necesario, una vez que ha terminado de ejecutarse el código se va al elemento superior, y verifica si para el evento desencadenado (para este caso el click) existe un manejador, como efectivamente si existe entonces entra a la función y ejecuta el código JavaScript, por lo tanto muestra de nuevo el mensaje y de nuevo sucede con el divPadre…uff ya vimos que no es que el código este mal…es que simplemente así es como se realiza la propagación de eventos.

Pero bueno, ya sabemos que nuestro código esta correcto, pero no hace lo que queremos que haga, así que tenemos dos diferentes formas para evitar este “problema”:

  • Retornar false: simplemente añadimos un return false al final de la función.
1: $("div.prop2").click(function () { 2: alert('Ha dado clic en el div: ' + $(this).attr('id')); 3: returnfalse; 4: })
  • Hacer uso del evento stopPropagation: Una solución en mi opinión mas bonita, primero declaramos una variable en la firma de la función (en el ejemplo uso e) y en lugar de retornar false le decimos e.stopPropagation()
1: $("div.prop3").click(function (e) {
2: alert('Ha dado clic en el div: ' + $(this).attr('id'));
3: e.stopPropagation();
4: })

Bueno espero que este post les sea de utilidad y les pueda ahorrar muchos dolores de cabeza y sobre todo que haya quedado claro que es la propagación de eventos.

Les dejo el ejemplo en donde el primera medida se propaga el evento, y luego se detiene haciendo uso del return false y el stopPropagation:

Descarga del ejemplo !