stopPropagation frente a stopImmediatePropagation
¿ Cuál es la diferencia entre event.stopPropagation()
y event.stopImmediatePropagation()
?
stopPropagation
impedirá que se ejecuten los controladores principalesstopImmediatePropagation
impedirá que se ejecuten los controladores principales y también cualquier otro controlador
Ejemplo rápido de la documentación de jquery:
$("p").click(function(event) {
event.stopImmediatePropagation();
});
$("p").click(function(event) {
// This function won't be executed
$(this).css("background-color", "#f00");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>example</p>
Tenga en cuenta que el orden de vinculación del evento es importante aquí.
Mostrar fragmento de código
Sorprendentemente, todas las demás respuestas sólo dicen la mitad de la verdad o, en realidad, ¡están equivocadas!
e.stopImmediatePropagation()
impide que se llame a cualquier controlador adicional para este evento, sin excepcionese.stopPropagation()
es similar, pero aún llama a todos los controladores para esta fase en este elemento si aún no se ha llamado
¿Qué fase?
Por ejemplo, un evento de clic siempre primero recorrerá todo el DOM (llamado “fase de captura”), finalmente llegará al origen del evento (“fase objetivo”) y luego volverá a burbujear (“fase de burbuja”). Y addEventListener()
puede registrar múltiples controladores tanto para la fase de captura como para la fase de burbuja de forma independiente. (La fase de destino llama a los controladores de ambos tipos en el objetivo sin distinguir).
Y esto es en lo que las otras respuestas son incorrectas:
- cita: "event.stopPropagation() permite ejecutar otros controladores en el mismo elemento"
- Corrección: si se detiene en la fase de captura, los controladores de la fase de burbuja nunca serán alcanzados, y además se los omitirá en el mismo elemento.
- cita: "event.stopPropagation() [...] se utiliza para detener las ejecuciones de su controlador principal correspondiente únicamente"
- Corrección: si la propagación se detiene en la fase de captura, tampoco se llama a los controladores de los hijos, incluido el objetivo , no solo a los padres.
- ...y: si la propagación se detiene en la fase de burbuja, ya se han llamado a todos los controladores de la fase de captura, incluidos los de los padres
Una explicación de la fase del evento de fiddle y mozilla.org con demostración.
Un pequeño ejemplo para demostrar cómo funcionan ambas paradas de propagación.
Mostrar fragmento de código
Hay tres controladores de eventos vinculados. Si no detenemos ninguna propagación, entonces debería haber cuatro alertas: tres en el div secundario y una en el div principal.
Si detenemos la propagación del evento, habrá 3 alertas (todas en el div secundario interno). Dado que el evento no se propagará hacia arriba en la jerarquía DOM, el div principal no lo verá y su controlador no se activará.
Si detenemos la propagación inmediatamente, solo habrá 1 alerta. Aunque hay tres controladores de eventos adjuntos al div secundario interno, solo se ejecuta 1 y cualquier propagación posterior se elimina inmediatamente, incluso dentro del mismo elemento.
Llegué tarde, pero tal vez pueda decir esto con un ejemplo específico:
Digamos, si tienes un <table>
, con <tr>
y luego <td>
. Ahora, digamos que configura 3 controladores de eventos para el <td>
elemento, luego, si lo hace event.stopPropagation()
en el primer controlador de eventos que configuró <td>
, todos los controladores de eventos <td>
aún se ejecutarán , pero el evento simplemente no se propagará a <tr>
o <table>
(y no sube y sube hasta <body>
, <html>
, document
, y window
).
Ahora, sin embargo, si usa event.stopImmediatePropagation()
su primer controlador de eventos, los otros dos controladores de eventos <td>
NO se ejecutarán y no se propagarán hasta <tr>
, <table>
(y no subirán hasta <body>
, <html>
, document
y window
).
Tenga en cuenta que no es sólo para <td>
. Para el resto de elementos se seguirá el mismo principio.