¿Cuál es la diferencia entre event.stopPropagation y event.preventDefault?
Parecen estar haciendo lo mismo... ¿
Uno es moderno y otro viejo? ¿O son compatibles con diferentes navegadores?
Cuando manejo eventos yo mismo (sin marco), siempre compruebo ambos y los ejecuto si están presentes. (Yo también return false
, pero tengo la sensación de que no funciona con eventos adjuntos node.addEventListener
).
Entonces, ¿por qué ambas cosas? ¿Debo seguir comprobando ambos? ¿O realmente hay una diferencia?
(Lo sé, muchas preguntas, pero todas son más o menos iguales =))
stopPropagation
evita una mayor propagación del evento actual en las fases de captura y burbujeo.
preventDefault
evita la acción predeterminada que realiza el navegador en ese evento.
Ejemplos
prevenir valor predeterminado
$("#but").click(function (event) {
event.preventDefault()
})
$("#foo").click(function () {
alert("parent click event fired!")
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo">
<button id="but">button</button>
</div>
detener la propagación
$("#but").click(function (event) {
event.stopPropagation()
})
$("#foo").click(function () {
alert("parent click event fired!")
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo">
<button id="but">button</button>
</div>
Con stopPropagation
, solo se llama al button
controlador de clics mientras que el div
controlador de clics nunca se activa.
Mientras que si usa preventDefault
, solo se detiene la acción predeterminada del navegador pero el controlador de clic del div aún se activa.
A continuación se muestran algunos documentos sobre las propiedades y métodos de eventos DOM de MDN:
event.cancelBubble
event.preventDefault()
event.returnValue
event.stopPropagation()
Para IE9 y FF puedes usar preventDefault y stopPropagation.
Para admitir IE8 e inferiores, reemplace stopPropagation
con cancelBubble
y reemplace preventDefault
conreturnValue
Terminología
De quirksmode.org :
captura de eventos
Cuando usas la captura de eventos
| | ---------------| |----------------- | elemento1 | | | | -----------| |----------- | | |elemento2 \ / | | | ------------------------- | | Evento CAPTURA | -----------------------------------el controlador de eventos del elemento1 se activa primero, el controlador de eventos del elemento2 se activa al final.
Evento burbujeante
Cuando usas la difusión de eventos
/\ ---------------| |----------------- | elemento1 | | | | -----------| |----------- | | |elemento2 | | | | | ------------------------- | | Evento BURBUJA | -----------------------------------el controlador de eventos del elemento2 se activa primero, el controlador de eventos del elemento1 se activa al final.
Cualquier evento que tenga lugar en el modelo de eventos del W3C se captura primero hasta que alcanza el elemento objetivo y luego vuelve a aparecer .
| | /\ -----------------| |--| |----------------- | elemento1 | | | | | | -------------| |--| |----------- | | |elemento2 \ / | | | | | -------------------------------- | | Modelo de evento del W3C | ------------------------------------------
Interfaz
Desde w3.org , para captura de eventos :
Si la captura
EventListener
desea evitar que se produzca un procesamiento adicional del evento, puede llamar alstopPropagation
método de laEvent
interfaz. Esto evitará que se envíe más el evento, aunque los adicionalesEventListeners
registrados en el mismo nivel jerárquico seguirán recibiendo el evento.stopPropagation
Una vez que se ha llamado al método de un evento , las llamadas posteriores a ese método no tienen ningún efecto adicional. Si no existen capturadores adicionales ystopPropagation
no se han llamado, el evento activa el correspondienteEventListeners
en el propio objetivo.
Para eventos burbujeantes :
Cualquier controlador de eventos puede optar por evitar una mayor propagación de eventos llamando al
stopPropagation
método de laEvent
interfaz. Si alguienEventListener
llama a este método, se activarán todos los adicionalesEventListeners
en la corriente , pero el burbujeo cesará en ese nivel.EventTarget
Solo se requiere una llamadastopPropagation
para evitar más burbujas.
Para cancelación de evento :
La cancelación se logra llamando al
Event
métodopreventDefault
. Si una o másEventListeners
llamadaspreventDefault
durante cualquier fase del evento fluyen, la acción predeterminada se cancelará.
Ejemplos
En los siguientes ejemplos, un clic en el hipervínculo en el navegador web activa el flujo del evento (se ejecutan los detectores de eventos) y la acción predeterminada del objetivo del evento (se abre una nueva pestaña).
HTML:
<div id="a">
<a id="b" href="http://www.google.com/" target="_blank">Google</a>
</div>
<p id="c"></p>
JavaScript:
var el = document.getElementById("c");
function capturingOnClick1(ev) {
el.innerHTML += "DIV event capture<br>";
}
function capturingOnClick2(ev) {
el.innerHTML += "A event capture<br>";
}
function bubblingOnClick1(ev) {
el.innerHTML += "DIV event bubbling<br>";
}
function bubblingOnClick2(ev) {
el.innerHTML += "A event bubbling<br>";
}
// The 3rd parameter useCapture makes the event listener capturing (false by default)
document.getElementById("a").addEventListener("click", capturingOnClick1, true);
document.getElementById("b").addEventListener("click", capturingOnClick2, true);
document.getElementById("a").addEventListener("click", bubblingOnClick1, false);
document.getElementById("b").addEventListener("click", bubblingOnClick2, false);
Ejemplo 1 : da como resultado la salida
DIV event capture
A event capture
A event bubbling
DIV event bubbling
Ejemplo 2 : agregar stopPropagation()
a la función
function capturingOnClick1(ev) {
el.innerHTML += "DIV event capture<br>";
ev.stopPropagation();
}
da como resultado la salida
DIV event capture
El detector de eventos evitó una mayor propagación hacia abajo y hacia arriba del evento. Sin embargo, no impidió la acción predeterminada (abrir una nueva pestaña).
Ejemplo 3 : agregar stopPropagation()
a la función
function capturingOnClick2(ev) {
el.innerHTML += "A event capture<br>";
ev.stopPropagation();
}
o la función
function bubblingOnClick2(ev) {
el.innerHTML += "A event bubbling<br>";
ev.stopPropagation();
}
da como resultado la salida
DIV event capture
A event capture
A event bubbling
Esto se debe a que ambos detectores de eventos están registrados en el mismo destino de evento. Los detectores de eventos impidieron una mayor propagación ascendente del evento. Sin embargo, no impidieron la acción predeterminada (abrir una nueva pestaña).
Ejemplo 4 : agregar preventDefault()
a cualquier función, por ejemplo
function capturingOnClick1(ev) {
el.innerHTML += "DIV event capture<br>";
ev.preventDefault();
}
evita que se abra una nueva pestaña.