477 votes

Comment empêcher l'événement onclick d'un parent de se déclencher lorsqu'une ancre enfant est cliquée ?

J'utilise actuellement jQuery pour rendre une division cliquable et j'ai également des ancres dans cette division. Le problème que je rencontre est que lorsque je clique sur une ancre, les deux événements de clics se déclenchent (pour la div et l'ancre). Comment puis-je empêcher l'événement onclick de la division de se déclencher lorsqu'une ancre est cliquée ?

Voici le code cassé :

JavaScript

var url = $("#clickable a").attr("href");

$("#clickable").click(function() {
    window.location = url;
    return true;
})

HTML

<div id="clickable">
    <!-- Other content. -->
    <a href="http://foo.com">I don't want #clickable to handle this click event.</a>
</div>

602voto

Rex M Points 80372

Les événements sont envoyés au point le plus élevé du DOM auquel un événement de clic a été attaché. Ainsi, dans votre exemple, même si vous n'aviez pas d'autres éléments explicitement cliquables dans la division, chaque élément enfant de la division ferait remonter son événement de clic dans le DOM jusqu'à ce que le gestionnaire d'événements de clic de la division l'attrape.

Il y a deux solutions à cela : vérifier qui est à l'origine de l'événement. jQuery passe un objet eventargs avec l'événement :

$("#clickable").click(function(e) {
    var senderElement = e.target;
    // Check if sender is the <div> element e.g.
    // if($(e.target).is("div")) {
    window.location = url;
    return true;
});

Vous pouvez également attacher un gestionnaire d'événement de clic à vos liens pour leur dire de arrêter le bouillonnement des événements après l'exécution de leur propre gestionnaire :

$("#clickable a").click(function(e) {
   // Do something
   e.stopPropagation();
});

5 votes

Excellente réponse. C'est bon de savoir qu'il y a aussi des options.

9 votes

+1 ! Attacher un gestionnaire de clic avec stopPropagation est une très bonne astuce, merci !

3 votes

Si vous aviez un tas d'éléments sur lesquels vous vouliez empêcher la propagation, vous pourriez trouver leur élément parent et l'empêcher de se propager là aussi. Ainsi, plutôt que d'intercepter tous les liens a dans un div, disons par exemple, il suffit d'intercepter le clic, même sur le div lui-même, et de l'empêcher d'aller plus haut, et le tour est joué.

139voto

Cleiton Points 4203

Utilisez stopPropagation voir un exemple :

$("#clickable a").click(function(e) {
   e.stopPropagation();
});

Comme dit par jQuery Docs :

stopPropagation empêche l'événement de remonter dans le DOM. et empêche les gestionnaires parents d'être notifiés de l'événement.

Gardez à l'esprit qu'il ne empêcher d'autres auditeurs de gérer cet événement (ex. plus d'un gestionnaire de clics pour un bouton), si ce n'est pas l'effet désiré, vous devez utiliser la fonction stopImmediatePropagation à la place.

0 votes

Faites attention à ne pas avoir accidentellement réglé les écouteurs d'événements pour qu'ils soient passifs.

8voto

Ivan Ivković Points 557

Si vous avez plusieurs éléments dans la division cliquable, vous devez procéder ainsi :

$('#clickable *').click(function(e){ e.stopPropagation(); });

1voto

Matt Ball Points 165937

Vous devez empêcher l'événement d'atteindre le parent (la division). Voir la partie sur les bulles aquí et des informations sur l'API de jQuery aquí .

0 votes

Cool. Merci pour l'info sur les bulles d'événements.

-4voto

ratnesh Points 11

Toutes les solutions sont compliquées et en jscript. Voici la version la plus simple :

var IsChildWindow=false;

function ParentClick()
{
    if(IsChildWindow==true)
    {
        IsChildWindow==false;
        return;
    }
    //do ur work here   
}

function ChildClick()
{
    IsChildWindow=true;
    //Do ur work here    
}

3 votes

Je pense que vous avez fait une erreur dans la ligne "IsChildWindow==false ;" - ne devrait-on pas dire "IsChildWindow = 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