155 votes

jQuery : la fonction de clic exclut les enfants.

J'essaie de me familiariser avec la fonction jQuery ".not()" et je rencontre un problème. Je voudrais que le div parent soit "cliquable" mais que si un utilisateur clique sur un élément enfant, le script ne soit pas appelé.

$(this).not(children()).click(function(){
   $(".example").fadeOut("fast");
});

le html :

<div class="example">
   <div>
      <p>This content is not affected by clicks.</p>
   </div>
</div>

213voto

Nick Craver Points 313913

Pour ce faire, arrêtez le clic sur l'enfant en utilisant .stopPropagation :

$(".example").click(function(){
  $(this).fadeOut("fast");
}).children().click(function(e) {
  return false;
});

Cela empêchera les clics des enfants de remonter au-delà de leur niveau et le parent ne recevra pas le clic.

.not() est utilisé un peu différemment, il filtre les éléments de votre sélecteur, par exemple :

<div class="bob" id="myID"></div>
<div class="bob"></div>

$(".bob").not("#myID"); //removes the element with myID

Pour le clic, votre problème est que le cliquer sur un enfant fait apparaître une bulle vers le parent et non pas que vous avez attaché par inadvertance un gestionnaire de clics à l'enfant.

0 votes

Merci Nick, je ne pense pas que ce soit ce que je recherchais. Je suis désolé de ne pas avoir été clair dans ma question. Je veux que la div.example entière s'efface, uniquement lorsque l'élément parent est cliqué, et non lorsque la div enfant est cliquée. J'aimerais en effet que l'utilisateur puisse cliquer sur le texte du paragraphe sans que celui-ci ne s'efface. Si l'utilisateur clique sur la division externe (division parent), tout s'efface.

0 votes

@superUntitled - Merci pour la clarification... la réponse est mise à jour pour faire cela, essayez.

0 votes

Cela pose problème lorsque d'autres événements sont liés aux éléments (onsubmit des éléments enfants ne fonctionne plus pour une raison quelconque).

192voto

MatCarey Points 589

J'utilise le balisage suivant et j'ai rencontré le même problème :

<ul class="nav">
    <li><a href="abc.html">abc</a></li>
    <li><a href="def.html">def</a></li>
</ul>

Ici, j'ai utilisé la logique suivante :

$(".nav > li").click(function(e){
    if(e.target != this) return; // only continue if the target itself has been clicked
    // this section only processes if the .nav > li itself is clicked.
    alert("you clicked .nav > li, but not it's children");
});

Pour ce qui est de la question exacte, je peux imaginer que cela fonctionne comme suit :

$(".example").click(function(e){
   if(e.target != this) return; // only continue if the target itself has been clicked
   $(".example").fadeOut("fast");
});

ou bien sûr l'inverse :

$(".example").click(function(e){
   if(e.target == this){ // only if the target itself has been clicked
       $(".example").fadeOut("fast");
   }
});

J'espère que cela vous aidera.

28 votes

Je pense que c'est la meilleure solution. Elle n'interfère en aucune façon avec les enfants et devrait être plus performante car elle n'enregistre pas potentiellement des milliers de callbacks s'il y a des milliers d'enfants.

4 votes

@l2aelba - vous devriez utiliser .on("click", ...) dans les versions récentes de jQuery comme .live() a été déprécié depuis la v1.7. Voir api.jquery.com/live

0 votes

Oui, @Chris I a posté le Nov 16 '12 à 10:12

26voto

dani24 Points 754

Ou vous pouvez aussi le faire :

$('.example').on('click', function(e) { 
   if( e.target != this ) 
       return false;

   // ... //
});

0 votes

Vous devez retourner false, pour éviter l'événement de clic dans les éléments enfants. La révision était erronée

10voto

npl len Points 71

Ma solution :

jQuery('.foo').on('click',function(event){
    if ( !jQuery(event.target).is('.foo *') ) {
        // code goes here
    } 
});

0 votes

Similaire à la solution au-dessus de la vôtre.

8voto

Noahone Points 71

Personnellement, j'ajouterais un gestionnaire de clic à l'élément enfant qui ne ferait rien d'autre que d'arrêter la propagation du clic. Cela ressemblerait donc à quelque chose comme :

$('.example > div').click(function (e) {
    e.stopPropagation();
});

0 votes

Quelle est la différence entre stopPropagation et qui renvoie des faux comme d'autres réponses le suggèrent ?

0 votes

Je crois que dans ce cas, ils seraient fonctionnels de la même manière, mais je pense que la propagation des arrêts est plus claire quant au but de ce qui est fait et laisse une meilleure chance de comprendre pourquoi c'est fait plus tard. Mais c'est discutable.

2 votes

Merci pour la clarification. Il semble que stopPropagation peut être plus propre car elle n'empêchera pas les événements sur les éléments enfants de se produire, ce qui peut se produire avec l'option return false .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X