Come fermare il gorgoglio degli eventi facendo clic sulla casella di controllo


183

Ho una casella di controllo che voglio eseguire alcune azioni Ajax sull'evento clic, tuttavia la casella di controllo è anche all'interno di un contenitore con il proprio comportamento di clic che non voglio eseguire quando si fa clic sulla casella di controllo. Questo esempio illustra cosa voglio fare:

$(document).ready(function() {
  $('#container').addClass('hidden');
  $('#header').click(function() {
    if ($('#container').hasClass('hidden')) {
      $('#container').removeClass('hidden');
    } else {
      $('#container').addClass('hidden');
    }
  });
  $('#header input[type=checkbox]').click(function(event) {
    // Do something
  });
});
#container.hidden #body {
  display: none;
}
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<div id="container">
  <div id="header">
    <h1>Title</h1>
    <input type="checkbox" name="test" />
  </div>
  <div id="body">
    <p>Some content</p>
  </div>
</div>

Tuttavia, non riesco a capire come fermare il gorgogliamento dell'evento senza causare la mancata esecuzione del comportamento predefinito del clic (casella di controllo selezionata / deselezionata).

Entrambi i seguenti fermano il gorgoglio degli eventi ma non cambiano lo stato della casella di controllo:

event.preventDefault();
return false;

2
Ho trovato un articolo su questo argomento che potrebbe essere utile ad altri Stack Overflower. Suggerimento rapido: fare clic su Fila tabella per attivare un clic Casella di controllo
Riso Peder

Risposte:


341

sostituire

event.preventDefault();
return false;

con

event.stopPropagation();

event.stopPropagation ()

Ferma il gorgogliamento di un evento verso gli elementi padre, impedendo a tutti i gestori genitori di essere avvisati dell'evento.

event.preventDefault ()

Impedisce al browser di eseguire l'azione predefinita. Utilizzare il metodo isDefaultPrevented per sapere se questo metodo è mai stato chiamato (su quell'oggetto evento).


4
per qualche motivo questo non funziona per me, ma return false ha funzionato.
Randy L,

3
Se si sta vincolando l'evento utilizzando il .live()metodo, questo non funzionerà. Dovrai usare return false;se stesso.
rahul,

2
Funziona usando il .on()metodo di jQuery (live ora è deprecato). Non sono riuscito a capire perché return false non funzionasse.
Styfle,

ho impiegato parecchio tempo a capire che event.preventDefault () non mostrava il segno di spunta in IE8, ma funzionava bene in altri browser. Ho trovato questa risposta dopo aver corretto e poi cercato su Google con preventDefault, IE8, casella di controllo come parola chiave, mi ha portato qui.
signonsridhar,

non ha funzionato per .. ma questa linea ha fatto (senza ritorno false) -> event.preventDefault (); event.stopPropagation ();
Kugan Kumar,


29

Non dimenticare IE:

if (event.stopPropagation) {    // standard
        event.stopPropagation();
    } else {    // IE6-8
        event.cancelBubble = true;
}

24
Questa risposta è del 2012. Nel 2015 dimentica IE.
Taylan,

8
Questo vale anche per IE9. La mia macchina di test IE9 si blocca su stopPropagation (), ma piace cancelBubble (). E alcune persone / organizzazioni usano ancora IE9 nel 2016, purtroppo. Quelli di noi con clienti aziendali non possono ignorarlo.
Chris Cober,

amo ie5 nel 2019
SuperUberDuper

5

Come altri hanno già detto, prova stopPropagation().

E c'è un secondo gestore da provare: event.cancelBubble = true;è un gestore specifico di IE, ma è supportato almeno in FF. Non ne so molto, dato che non l'ho usato da solo, ma potrebbe valere la pena tentare, se tutto il resto fallisce.


5

Questo è un ottimo esempio per comprendere il concetto di bolle di eventi. Sulla base delle risposte di cui sopra, il codice finale apparirà come indicato di seguito. Se l'utente fa clic sulla casella di controllo, la propagazione dell'evento all'elemento principale "intestazione" verrà interrotta event.stopPropagation();.

$(document).ready(function() {
            $('#container').addClass('hidden');
            $('#header').click(function() {
                if($('#container').hasClass('hidden')) {
                    $('#container').removeClass('hidden');
                } else {
                    $('#container').addClass('hidden');
                }
            });
          $('#header input[type=checkbox]').click(function(event) {
              if (event.stopPropagation) {    // standard
                   event.stopPropagation();
               } else {    // IE6-8
                    event.cancelBubble = true;
               }
          });     
  });

5

Quando si utilizza jQuery non è necessario chiamare una funzione di arresto separata.

Puoi semplicemente tornare falsenel gestore dell'evento

Ciò interromperà l'evento e annullerà il gorgoglio.

Vedi anche event.preventDefault () vs. return false

Dai documenti di jQuery:

Questi gestori, pertanto, possono impedire l'attivazione del gestore delegato chiamando event.stopPropagation()o restituendo false.


1

Ringraziamo @mehras per il codice. Ho appena creato uno snippet per dimostrarlo perché pensavo che sarebbe stato apprezzato e volevo una scusa per provare quella funzione.

$(document).ready(function() {
  $('#container').addClass('hidden');
  $('#header').click(function() {
    if ($('#container').hasClass('hidden')) {
      $('#container').removeClass('hidden');
    } else {
      $('#container').addClass('hidden');
    }
  });
  $('#header input[type=checkbox]').click(function(event) {
    if (event.stopPropagation) { // standard
      event.stopPropagation();
    } else { // IE6-8
      event.cancelBubble = true;
    }
  });
});
div {
  text-align: center;
  padding: 2em;
  font-size: 1.2em
}

.hidden {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="header"><input type="checkbox" />Checkbox won't bubble the event, but this text will.</div>
<div id="container">click() bubbled up!</div>


Codice che mostra effettivamente come utilizzare la variabile evento, grazie.
Moshe Binieli,

-1

In angularjs dovrebbe funzionare:

event.preventDefault(); 
event.stopPropagation();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.