web-dev-qa-db-fra.com

Comment faire pour que l'événement de clic se déclenche UNIQUEMENT sur le parent DIV, pas sur les enfants?

J'ai une DIV avec une foobar classée et quelques DIV à l'intérieur de cette DIV qui sont non classées, mais je suppose qu'elles héritent de la classe foobar:

$('.foobar').on('click', function() { /*...do stuff...*/ });

Je veux que cela ne se déclenche que lorsque vous cliquez quelque part dans la DIV, mais pas sur ses DIV enfants.

164
CaptSaltyJack

Si le e.target est le même élément que this, vous n'avez pas cliqué sur un descendant.

$('.foobar').on('click', function(e) {
  if (e.target !== this)
    return;
  
  alert( 'clicked the foobar' );
});
.foobar {
  padding: 20px; background: yellow;
}
span {
  background: blue; color: white; padding: 8px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class='foobar'> .foobar (alert) 
  <span>child (no alert)</span>
</div>

374
user1106925

Il existe une autre méthode qui fonctionne si vous ne craignez pas uniquement les nouveaux navigateurs. Il suffit d'ajouter le CSS

pointer-events: none;

à tous les enfants de la div que vous voulez capturer le clic. Voici les tables de soutien

http://caniuse.com/#feat=pointer-events

37
hobberwickey

Vous pouvez utiliser des bulles en votre faveur:

$('.foobar').on('click', function(e) {
    // do your thing.
}).on('click', 'div', function(e) {
    // clicked on descendant div
    e.stopPropagation();
});
23
ori
//bind `click` event handler to the `.foobar` element(s) to do work,
//then find the children of all the `.foobar` element(s)
//and bind a `click` event handler to them that stops the propagation of the event
$('.foobar').on('click', function () { ... }).children().on('click', function (event) {
    event.stopPropagation();
    //you can also use `return false;` which is the same as `event.preventDefault()` and `event.stopPropagation()` all in one (in a jQuery event handler)
});

Cela arrêtera la propagation (le bullage) de l'événement click sur l'un des éléments enfants du ou des éléments .foobar de sorte que l'événement n'atteigne pas les éléments .foobar pour déclencher leur ou leurs gestionnaires d'événements.

Voici une démo: http://jsfiddle.net/bQQJP/

19
Jasper
$(".advanced ul li").live('click',function(e){
    if(e.target != this) return;
    //code
    // this code will execute only when you click to li and not to a child
})
2
Michalis

Je n'ai pas obtenu la réponse acceptée au travail, mais cela semble faire l'affaire, au moins dans Vanilla JS.

if(e.target !== e.currentTarget) return;
2
Jens Törnell

Mon cas est similaire, mais c’est l’occasion dans laquelle vous avez peu de foobar- s et que vous ne voulez fermer qu’un - par clic:

Trouver le cas parent

$(".foobar-close-button-class").on("click", function () {
    $(this).parents('.foobar').fadeOut( 100 );
    // 'this' - means that you finding some parent class from '.foobar-close-button-class'
    // '.parents' -means that you finding parent class with name '.foobar'
});

Trouver un cas d'enfant

$(".foobar-close-button-class").on("click", function () {
    $(this).child('.foobar-close-button-child-class').fadeOut( 100 );
    // 'this' - means that you finding some child class from '.foobar-close-button-class'
    // '.child' -means that you finding child class with name '.foobar-close-button-child-class'
});
1
Wukadin

J'ai eu le même problème et suis venu avec cette solution (basée sur les autres réponses)

 $( ".newsletter_background" ).click(function(e) {
    if (e.target == this) {
        $(".newsletter_background").hide();
    } 
});

En gros, si la cible est la div, lancez le code, sinon ne faites rien (ne le cachez pas)

0
Wonx2150

Si vous ne pouvez pas utiliser pointer-events: none; et que vous ciblez les navigateurs modernes, vous pouvez utiliser composedPath pour détecter un clic direct sur l'objet de la manière suivante:

element.addEventListener("click", function (ev) {
    if (ev.composedPath()[0] === this) {
        // your code here ...
    }
})

Vous pouvez en savoir plus sur compoundPath ici: https://developer.mozilla.org/en-US/docs/Web/API/Event/composedPath

0
Xenxier

Vous pouvez utiliser event.currentTarget. Il ne fera que cliquer sur événement uniquement pour celui qui a eu l'événement.

target = e => {
    console.log(e.currentTarget);
  };
<ul onClick={target} className="folder">
      <li>
        <p>
          <i className="fas fa-folder" />
        </p>
      </li>
    </ul>

0
Dejan Markovic