javascript - prevent - vanilla js stoppropagation




Qual è la differenza tra event.stopPropagation ed event.preventDefault? (5)

Sembrano fare la stessa cosa ... Uno è moderno e uno vecchio? Oppure sono supportati da diversi browser?

Quando gestisco gli eventi da solo (senza framework), controllo sempre entrambi e eseguo entrambi se presente. ( node.addEventListener anche return false , ma ho la sensazione che non funzioni con gli eventi associati a node.addEventListener ).

Allora perché entrambi? Devo continuare a controllare per entrambi? O c'è davvero una differenza?

(Lo so, molte domande, ma sono tutte uguali =))


Terminologia

Da quirksmode.org :

Cattura di eventi

Quando usi la cattura degli eventi

               | |
---------------| |-----------------
| element1     | |                |
|   -----------| |-----------     |
|   |element2  \ /          |     |
|   -------------------------     |
|        Event CAPTURING          |
-----------------------------------

il gestore di eventi di element1 scocca per primo, il gestore di eventi di element2 scocca per ultimo.

Bubbling di eventi

Quando usi il bubbling degli eventi

               / \
---------------| |-----------------
| element1     | |                |
|   -----------| |-----------     |
|   |element2  | |          |     |
|   -------------------------     |
|        Event BUBBLING           |
-----------------------------------

il gestore di eventi di element2 si attiva per primo, il gestore di eventi di element1 si attiva per ultimo.

Qualsiasi evento che si svolge nel modello di eventi W3C viene prima catturato fino a raggiungere l'elemento di destinazione e quindi bolle di nuovo .

                 | |  / \
-----------------| |--| |-----------------
| element1       | |  | |                |
|   -------------| |--| |-----------     |
|   |element2    \ /  | |          |     |
|   --------------------------------     |
|        W3C event model                 |
------------------------------------------

Interfaccia

Da w3.org , per l' acquisizione di eventi :

Se l'acquisizione di EventListener desidera impedire l'ulteriore elaborazione dell'evento, può chiamare il metodo stopPropagation dell'interfaccia Event . Ciò impedirà l'ulteriore invio dell'evento, sebbene ulteriori EventListeners registrati allo stesso livello gerarchico continueranno a ricevere l'evento. Una volta chiamato il metodo stopPropagation un evento, ulteriori chiamate a tale metodo non hanno alcun effetto aggiuntivo. Se nessun catturatore aggiuntivo esiste e stopPropagation non è stato chiamato, l'evento attiva gli EventListeners appropriati sul target stesso.

Per il bubbling degli eventi :

Qualsiasi gestore di eventi può scegliere di impedire la propagazione di altri eventi chiamando il metodo stopPropagation dell'interfaccia Event . Se EventListener chiama questo metodo, verranno attivati ​​tutti EventListeners aggiuntivi sul EventTarget corrente, ma il bubbling cesserà a quel livello. È necessaria una sola chiamata a stopPropagation per prevenire ulteriori ribollimenti.

Per la cancellazione dell'evento :

L'annullamento si ottiene chiamando il metodo preventDefault Event . Se uno o più EventListeners chiamano preventDefault durante qualsiasi fase del flusso di eventi, l'azione predefinita verrà annullata.

Esempi

Nei seguenti esempi, un clic sul collegamento ipertestuale nel browser Web attiva il flusso dell'evento (i listener di eventi vengono eseguiti) e l'azione predefinita del target dell'evento (viene aperta una nuova scheda).

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

Esempio 1 : risulta nell'output

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

Esempio 2 : aggiunta stopPropagation() alla funzione

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

risultati nell'output

DIV event capture

L'ascoltatore dell'evento ha impedito ulteriori propagazioni verso il basso e verso l'alto dell'evento. Tuttavia non ha impedito l'azione predefinita (una nuova apertura di tabulazione).

Esempio 3 : aggiunta stopPropagation() alla funzione

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

o la funzione

function bubblingOnClick2(ev) {
    el.innerHTML += "A event bubbling<br>";
    ev.stopPropagation();
}

risultati nell'output

DIV event capture
A event capture
A event bubbling

Questo perché entrambi gli ascoltatori di eventi sono registrati sullo stesso target dell'evento. Gli ascoltatori dell'evento hanno impedito un'ulteriore propagazione ascendente dell'evento. Tuttavia non hanno impedito l'azione predefinita (una nuova apertura di tabulazione).

Esempio 4 : aggiunta preventDefault() a qualsiasi funzione, ad esempio

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

impedisce l'apertura di una nuova scheda.


Event.preventDefault- arresta il comportamento predefinito del browser. Ora arriva qual è il comportamento predefinito del browser. Supponiamo di avere un tag di ancoraggio e ha un attributo href e questo tag di ancoraggio è nidificato all'interno di un tag div che ha un evento click. Il comportamento predefinito del tag di ancoraggio è quando si fa clic sul tag di ancoraggio che deve navigare, ma ciò che event.preventDefault fa è che interrompe la navigazione in questo caso. Ma non si ferma mai il gorgoglio dell'evento o l'escalation dell'evento, ad es

<div class="container">
 <a href="#" class="element">Click Me!</a>
</div>

$('.container').on('click', function(e) {
 console.log('container was clicked');
});

$('.element').on('click', function(e) {
  e.preventDefault(); // Now link won't go anywhere
  console.log('element was clicked');
});

Il risultato sarà

"l'elemento è stato cliccato"

"il contenitore è stato cliccato"

Ora event.StopPropation interrompe il bubbling dell'evento o l'escalation dell'evento. Ora con l'esempio sopra

$('.container').on('click', function(e) {
  console.log('container was clicked');
});

$('.element').on('click', function(e) {
  e.preventDefault(); // Now link won't go anywhere
  e.stopPropagation(); // Now the event won't bubble up
 console.log('element was clicked');
});

Il risultato sarà

"l'elemento è stato cliccato"

Per maggiori informazioni, consultare questo link https://codeplanet.io/preventdefault-vs-stoppropagation-vs-stopimmediatepropagation/


event.preventDefault(); Interrompe l'azione predefinita di un elemento.

event.stopPropagation(); Impedisce all'evento di ribollire nell'albero DOM, impedendo a qualsiasi gestore genitore di essere informato dell'evento.

Ad esempio, se esiste un collegamento con un metodo di clic allegato a un DIV o FORM che ha anche un metodo di clic collegato, impedirà l' DIV metodo di selezione DIV o FORM .


stopPropagation interrompe l'evento dal ribollire della catena di eventi.

preventDefault impedisce l'azione predefinita che il browser esegue su quell'evento.

Diciamo che hai

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

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

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

Esempio

$("#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 viene chiamato solo il gestore dei clic sui pulsanti e il gestore di clic di div non viene mai attivato.

Nei casi in cui si preventDefault solo l'impostazione predefinita, l'azione predefinita del browser viene interrotta, ma il gestore di clic del div viene comunque attivato.

Di seguito sono riportati alcuni documenti sugli oggetti evento DOM da MDN e MSDN

MDN:

Per IE9 e FF puoi semplicemente usare preventDefault e stopPropagation.

Per supportare IE8 e inferiore, sostituire stopPropagation con cancelBubble e sostituire preventDefault con returnValue


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





stoppropagation