¿Cuál es la diferencia entre event.stopPropagation y event.preventDefault?

Resuelto Rudie asked hace 13 años • 10 respuestas

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 =))

Rudie avatar May 11 '11 18:05 Rudie
Aceptado

stopPropagationevita una mayor propagación del evento actual en las fases de captura y burbujeo.

preventDefaultevita 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>
Expandir fragmento

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>
Expandir fragmento

Con stopPropagation, solo se llama al buttoncontrolador de clics mientras que el divcontrolador 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 stopPropagationcon cancelBubbley reemplace preventDefaultconreturnValue

Raynos avatar May 11 '2011 11:05 Raynos

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 EventListenerdesea evitar que se produzca un procesamiento adicional del evento, puede llamar al stopPropagationmétodo de la Eventinterfaz. Esto evitará que se envíe más el evento, aunque los adicionales EventListenersregistrados 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 y stopPropagationno se han llamado, el evento activa el correspondiente EventListenersen el propio objetivo.

Para eventos burbujeantes :

Cualquier controlador de eventos puede optar por evitar una mayor propagación de eventos llamando al stopPropagationmétodo de la Eventinterfaz. Si alguien EventListenerllama a este método, se activarán todos los adicionales EventListenersen la corriente , pero el burbujeo cesará en ese nivel. EventTargetSolo se requiere una llamada stopPropagationpara evitar más burbujas.

Para cancelación de evento :

La cancelación se logra llamando al Eventmétodo preventDefault . Si una o más EventListenersllamadas preventDefaultdurante 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.

a5hk avatar May 30 '2014 12:05 a5hk