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


Parece que están haciendo lo mismo ... ¿Es uno moderno y viejo? ¿O son compatibles con diferentes navegadores?

Cuando manejo eventos yo mismo (sin marco) siempre compruebo ambos y ejecuto ambos si están presentes. (Yo también return false, pero tengo la sensación de que no funciona con eventos adjuntos con node.addEventListener)

Entonces, ¿por qué ambos? ¿Debo seguir buscando ambos? ¿O hay realmente una diferencia?

(Lo sé, muchas preguntas, pero todas son más o menos iguales =))


600
2018-05-11 11:45


origen


Respuestas:


stopPropagation evita que el evento burbujee en la cadena de eventos.

preventDefault impide la acción predeterminada que realiza el navegador en ese evento.

Digamos que tienes

<div id="foo">
 <button id="but" />
</div>

$("#foo").click(function() {
   // mouse click on div
});

$("#but").click(function(ev) {
   // mouse click on button
   ev.stopPropagation();
});

Ejemplo

$("#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>

$("#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 el botones hacer clic en controlador se llama y el divs clic manejador nunca dispara

Donde como si solo preventDefault solo la acción predeterminada de los navegadores se detiene pero el manejador de clics de div todavía se dispara.

A continuación se encuentran algunos documentos sobre los objetos de evento DOM de MDN y MSDN

MDN:

Para IE9 y FF, puede usar preventDefault y stopPropagation.

Para admitir IE8 y reemplazar inferior stopPropagation con cancelBubble y reemplazar preventDefault con returnValue


785
2018-05-11 11:46



Terminología

De quirksmode.org:

Captura de eventos

Cuando usa captura de eventos

               | |
--------------- | | -----------------
| element1 | | |
| ----------- | | ----------- |
| | element2 \ / | |
| ------------------------- |
| Evento CAPTURANDO |
-----------------------------------

el controlador de eventos del elemento1 dispara primero, el controlador de eventos del elemento2 dispara al último.

Evento burbujeante

Cuando usa evento de burbujeo

               / \
--------------- | | -----------------
| element1 | | |
| ----------- | | ----------- |
| | elemento2 | | | |
| ------------------------- |
| Evento BUBBLING |
-----------------------------------

el controlador de eventos de element2 dispara primero, el controlador de eventos de element1 se dispara al último.

Cualquier evento que tenga lugar en el modelo de evento W3C se captura primero hasta que alcanza el elemento objetivo y luego vuelve a burbujear.

                 | | / \
----------------- | | - | | -----------------
| element1 | | | | |
| ------------- | | - | | ----------- |
| | element2 \ / | | | |
| -------------------------------- |
| Modelo de evento W3C |
------------------------------------------

Interfaz

De w3.org, para captura de evento:

Si la captura EventListener desea evitar el procesamiento posterior de   el evento de ocurrir puede llamar al stopPropagation método de la    Event interfaz. Esto evitará un mayor despacho del evento,   aunque adicional EventListeners registrado en la misma jerarquía   nivel todavía recibirá el evento. Una vez que un evento stopPropagationmétodo ha sido llamado, las llamadas posteriores a ese método no tienen   efecto adicional Si no existen capturadores adicionales y    stopPropagation no se ha llamado, el evento desencadena el   apropiado EventListeners en el objetivo mismo.

por evento burbujeo:

Cualquier controlador de eventos puede optar por evitar la propagación de eventos adicionales por   llamando al stopPropagation método de la Event interfaz. Si alguna    EventListener llama a este método, todos adicionales EventListeners sobre el   corriente EventTarget se activará pero el burbujeo cesará en ese   nivel. Solo una llamada a stopPropagation es necesario para evitar más   burbujeando

por cancelación de evento:

La cancelación se realiza llamando al Eventes preventDefault   método. Si uno o más EventListeners llamada preventDefault durante   cualquier fase del flujo de eventos la acción predeterminada se cancelará.

Ejemplos

En los ejemplos siguientes, un clic en el hipervínculo en el navegador web desencadena el flujo del evento (los oyentes del evento se ejecutan) 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: resulta en la salida

DIV event capture
A event capture
A event bubbling
DIV event bubbling

Ejemplo 2: agregando stopPropagation() a la función

function capturingOnClick1(ev) {
    el.innerHTML += "DIV event capture<br>";
    ev.stopPropagation();
}

resultados en la salida

DIV event capture

El oyente del evento impidió una mayor propagación hacia abajo y hacia arriba del evento. Sin embargo, no evitó la acción predeterminada (una nueva apertura de pestañas).

Ejemplo 3: agregando 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();
}

resultados en 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 objetivo de evento. Los oyentes del evento impidieron una mayor propagación hacia arriba del evento. Sin embargo, no impidieron la acción predeterminada (una nueva apertura de pestañas).

Ejemplo 4: agregando preventDefault() a cualquier función, por ejemplo

function capturingOnClick1(ev) {
    el.innerHTML += "DIV event capture<br>";
    ev.preventDefault();
}

impide que se abra una nueva pestaña.


178
2018-05-30 12:16



falso retorno;


return false; hace 3 cosas separadas cuando lo llamas:

  1. event.preventDefault() - Se detiene el comportamiento predeterminado de los navegadores.
  2. event.stopPropagation() - Impide que el evento se propague (o "burbujee") el DOM.
  3. Detiene la ejecución de devolución de llamada y regresa inmediatamente cuando se llama.

Tenga en cuenta que este comportamiento difiere de los controladores de eventos normales (no jQuery), en el cual, notablemente, return false no detiene el evento de burbujeo.

preventDefault ();


preventDefault(); hace una cosa: detiene el comportamiento predeterminado de los navegadores

¿Cuándo usarlos?


Sabemos lo que hacen, pero ¿cuándo usarlos? Simplemente depende de lo que quiere lograr. Utilizar preventDefault(); si desea "solo" evitar el comportamiento predeterminado del navegador. Use return falso; cuando desea evitar el comportamiento predeterminado del navegador y evitar que el evento propague el DOM. En la mayoría de las situaciones en las que usarías, devuelve falso; lo que realmente quieres es preventDefault().

Ejemplos:


Tratemos de entender con ejemplos:

Veremos un ejemplo JAVASCRIPT puro

Ejemplo 1:

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    alert('Link Clicked');
  }

  function executeParent() {
    alert('div Clicked');
  }
</script>

Ejecute el código anterior, verá el hipervínculo 'Haga clic aquí para visitar   stackoverflow.com ' ahora si haces clic en ese enlace primero obtendrás   la alerta de javascript Enlace hecho clicA continuación obtendrá el javascript   alerta div Clicked e inmediatamente serás redirigido a   stackoverflow.com.

Ejemplo 2:

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    event.preventDefault();
    event.currentTarget.innerHTML = 'Click event prevented'
    alert('Link Clicked');
  }

  function executeParent() {
    alert('div Clicked');
  }
</script>

Ejecute el código anterior, verá el hipervínculo 'Haga clic aquí para visitar   stackoverflow.com 'ahora si primero haces clic en ese enlace obtendrás   la alerta de javascript Enlace hecho clicA continuación obtendrá el javascript   alerta div Clicked A continuación, verá el hipervínculo 'Haga clic aquí para   visita stackoverflow.com 'reemplazado por el texto' Click event avoided '   y lo harás no ser redirigido a stackoverflow.com. Esto es debido al método event.preventDefault () que utilizamos para evitar el clic predeterminado   acción a ser activada

Ejemplo 3:

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    event.stopPropagation();
    event.currentTarget.innerHTML = 'Click event prevented'
    alert('Link Clicked');
  }

  function executeParent() {
    alert('div Clicked');
  }
</script>

Esta vez, si hace clic en Vincular, la función ejecutarParente () no   ser llamado y no recibirá la alerta de javascript div Clicked   esta vez. Esto se debe a que hemos impedido la propagación al   padre div utilizando el método event.stopPropagation (). Luego verás el   hipervínculo 'Haga clic aquí para visitar stackoverflow.com' reemplazado por el texto   'El evento Click se va a ejecutar' e inmediatamente estará   redirigido a stackoverflow.com. Esto es porque no hemos prevenido   la acción de clic predeterminada para activar esta vez usando   método event.preventDefault ()

Ejemplo 4:

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    event.preventDefault();
    event.stopPropagation();
    event.currentTarget.innerHTML = 'Click event prevented'
    alert('Link Clicked');
  }

  function executeParent() {
    alert('Div Clicked');
  }
</script>

Si hace clic en el enlace, la función executeParent () no será   llamado y no recibirá la alerta de javascript. Esto es debido a nosotros   habiendo impedido la propagación al div principal usando   método event.stopPropagation () A continuación, verá el hipervínculo 'Clic   aquí para visitar stackoverflow.com 'reemplazado por el texto' Haga clic en evento   prevenido 'y no se le redireccionará a stackoverflow.com. Esta   es porque hemos evitado que se active la acción de clic predeterminada   esta vez usando el método event.preventDefault ().

Ejemplo 5:

Para el resultado falso, tengo tres ejemplos y todos parecen estar haciendo exactamente lo mismo (simplemente devuelve falso), pero en realidad el   los resultados son bastante diferentes Esto es lo que realmente sucede en cada uno de   lo anterior.

casos:

  1. Regresando falso desde un controlador de eventos en línea evita que el navegador navegue a la dirección del enlace, pero no detiene el hecho de que el evento se propague a través del DOM.
  2. Regresando falso desde un controlador de eventos jQuery evita que el navegador navegue a la dirección del enlace e impide que el evento se propague a través del DOM.
  3. Regresando falso de un controlador de eventos DOM habitual no hace absolutamente nada.

Veremos los tres ejemplos.

  1. Inline return falso.

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='return false'>Click here to visit stackoverflow.com</a>
</div>
<script>
  var link = document.querySelector('a');

  link.addEventListener('click', function() {
    event.currentTarget.innerHTML = 'Click event prevented using inline html'
    alert('Link Clicked');
  });


  function executeParent() {
    alert('Div Clicked');
  }
</script>

  1. Regresando falso desde un controlador de eventos jQuery.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <a href='https://stackoverflow.com'>Click here to visit stackoverflow.com</a>
</div>
<script>
  $('a').click(function(event) {
    alert('Link Clicked');
    $('a').text('Click event prevented using return FALSE');
    $('a').contents().unwrap();
    return false;
  });
  $('div').click(function(event) {
    alert('Div clicked');
  });
</script>

  1. Devolución falsa de un controlador de eventos DOM habitual.

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    event.currentTarget.innerHTML = 'Click event prevented'
    alert('Link Clicked');
    return false
  }

  function executeParent() {
    alert('Div Clicked');
  }
</script>

Espero que estos ejemplos sean claros. Intente ejecutar todos estos ejemplos en un archivo html para ver cómo funcionan.


46
2018-05-27 07:14



Esta es la cita de aquí

Event.preventDefault

El método preventDefault evita que un evento lleve a cabo su funcionalidad predeterminada. Por ejemplo, usaría preventDefault en un elemento A para dejar de hacer clic en ese elemento y dejar la página actual:

//clicking the link will *not* allow the user to leave the page 
myChildElement.onclick = function(e) { 
    e.preventDefault(); 
    console.log('brick me!'); 
};

//clicking the parent node will run the following console statement because event propagation occurs
logo.parentNode.onclick = function(e) { 
    console.log('you bricked my child!'); 
};

Mientras que la funcionalidad predeterminada del elemento es bricked, el evento continúa burbujeando el DOM.

Event.stopPropagation

El segundo método, stopPropagation, permite que ocurra la funcionalidad predeterminada del evento pero evita que el evento se propague:

//clicking the element will allow the default action to occur but propagation will be stopped...
myChildElement.onclick = function(e) { 
    e.stopPropagation();
    console.log('prop stop! no bubbles!'); 
};

//since propagation was stopped by the child element's onClick, this message will never be seen!
myChildElement.parentNode.onclick = function(e) { 
    console.log('you will never see this message!'); 
};

StopPropagation detiene de manera efectiva que los elementos padre conozcan un evento dado en su hijo.

Mientras que un método de parada simple nos permite manejar eventos rápidamente, es   importante pensar qué es exactamente lo que quiere que suceda con   burbujeando Apuesto a que todo lo que un desarrollador realmente quiere es prevenirDefault   90% del tiempo! "Detener" incorrectamente un evento podría causarte   numerosos problemas en el futuro; sus complementos pueden no funcionar y su   Los complementos de terceros podrían ser brutos. O peor aún, tu código   rompe otra funcionalidad en un sitio.


14
2018-03-25 14:55



event.preventDefault(); Detiene la acción predeterminada de un elemento.

event.stopPropagation(); Evita que el evento burbujee en el árbol DOM, evitando que se notifique a ningún controlador principal del evento.

Por ejemplo, si hay un enlace con un método de clic adjunto dentro de un DIV o FORM que también tiene un método de clic adjunto, evitará DIV o FORM haga clic en método desde el disparo.


0
2018-05-06 11:32



$("#but").click(function(event){
console.log("hello");
  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>


-3
2017-09-10 03:57