Comment arrêter l'événement bouillonnant sur la case à cocher cliquez sur

186

J'ai une case à cocher que je veux effectuer une action Ajax sur l'événement de clic, mais la case à cocher est également à l'intérieur d'un conteneur avec son propre comportement de clic que je ne veux pas exécuter lorsque la case à cocher est cliquée. Cet exemple illustre ce que je veux faire:

$(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="https://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>

Cependant, je ne peux pas comprendre comment arrêter l'événement bouillonnant sans que le comportement de clic par défaut (la case à cocher soit cochée / décochée) ne s'exécute pas.

Les deux éléments suivants arrêtent la propagation de l'événement, mais ne modifient pas non plus l'état de la case à cocher:

event.preventDefault();
return false;
roryf
la source
2
J'ai trouvé un article sur ce sujet qui pourrait être utile à d'autres Stack Overflowers. Astuce rapide: Cliquez sur la ligne du tableau pour déclencher un clic sur une case à cocher
Peder Rice

Réponses:

349

remplacer

event.preventDefault();
return false;

avec

event.stopPropagation();

event.stopPropagation ()

Arrête la propagation d'un événement vers les éléments parents, empêchant les gestionnaires parents d'être notifiés de l'événement.

event.preventDefault ()

Empêche le navigateur d'exécuter l'action par défaut. Utilisez la méthode isDefaultPrevented pour savoir si cette méthode a déjà été appelée (sur cet objet événement).

rahul
la source
4
pour une raison quelconque, cela ne fonctionne pas pour moi, mais return false l'a fait.
Randy L
3
Si vous liez l'événement à l'aide de la .live()méthode, cela ne fonctionnera pas. Vous devrez vous en servir return false;.
rahul
2
Cela fonctionne en utilisant la .on()méthode de jQuery (live est désormais obsolète). Je ne pouvais pas comprendre pourquoi return false ne fonctionnait pas.
styfle
J'ai passé un certain temps à comprendre que event.preventDefault () n'affichait pas la coche dans IE8, mais fonctionnait bien dans d'autres navigateurs. J'ai trouvé cette réponse après avoir corrigé puis googlé avec preventDefault, IE8, case à cocher comme mot-clé, m'a amené ici.
signonsridhar
n'a pas fonctionné pour .. mais ces deux lignes ont fonctionné (sans retour faux) -> event.preventDefault (); event.stopPropagation ();
Kugan Kumar
32

Utilisez la méthode stopPropagation:

event.stopPropagation();
Patrice Neff
la source
29

N'oubliez pas IE:

if (event.stopPropagation) {    // standard
        event.stopPropagation();
    } else {    // IE6-8
        event.cancelBubble = true;
}
Faraz Kelhini
la source
26
Cette réponse date de 2012. En 2015, n'oubliez pas IE.
Taylan
8
Cela s'applique également à IE9. Ma machine de test IE9 s'étouffe sur stopPropagation (), mais aime cancelBubble (). Et certaines personnes / organisations utilisent toujours IE9 en 2016, malheureusement. Ceux d'entre nous qui ont des entreprises clientes ne peuvent ignorer cela.
Chris Cober
j'aime ie5 en 2019
SuperUberDuper
6

Lorsque vous utilisez jQuery, vous n'avez pas besoin d'appeler une fonction d'arrêt séparée.

Vous pouvez simplement revenir falsedans le gestionnaire d'événements

Cela arrêtera l'événement et annulera le bouillonnement.

Voir également event.preventDefault () vs return false

À partir de la documentation jQuery:

Ces gestionnaires peuvent par conséquent empêcher le gestionnaire délégué de se déclencher en appelant event.stopPropagation()ou en retournant false.

NéerlandaisKevv
la source
5

Comme d'autres l'ont mentionné, essayez stopPropagation().

Et il y a un deuxième gestionnaire à essayer: event.cancelBubble = true;c'est un gestionnaire spécifique à IE, mais il est pris en charge dans au moins FF. Je ne sais pas vraiment grand-chose, car je ne l'ai pas utilisé moi-même, mais cela vaut peut-être la peine d'être essayé, si tout le reste échoue.

peirix
la source
5

Ceci est un excellent exemple pour comprendre le concept d'événement bouillonnant. Sur la base des réponses ci-dessus, le code final ressemblera à celui mentionné ci-dessous. Lorsque l'utilisateur clique sur la case à cocher, la propagation de l'événement vers son élément parent «en-tête» sera interrompue 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;
               }
          });     
  });
mehras
la source
1

Merci à @mehras pour le code. Je viens de créer un extrait de code pour le démontrer car je pensais que ce serait apprécié et je voulais une excuse pour essayer cette fonctionnalité.

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

user2503764
la source
Code qui montre en fait comment utiliser la variable d'événement, merci.
Moshe Binieli
0

Voici une astuce qui a fonctionné pour moi:

handleClick = e => {
    if (e.target === e.currentTarget) {
        // do something
    } else {
        // do something else
    }
}

Explication: j'ai joint handleClick à un arrière-plan d'une fenêtre modale, mais il s'est également déclenché à chaque clic à l'intérieur d'une fenêtre modale (car il était DANS le div de fond). J'ai donc ajouté la condition (e.target === e.currentTarget), qui n'est remplie que lorsqu'un clic est effectué sur un fond.

MarcinOstaszewski
la source
pouvez-vous expliquer votre réponse quant à son fonctionnement, afin que les futurs lecteurs aient une image claire.
Not A Bot
Oui s'il vous plaît. où va ce code
John Lord
-1

Dans angularjs, cela devrait fonctionner:

event.preventDefault(); 
event.stopPropagation();
Kugan Kumar
la source