Comment puis-je empêcher l'événement onclick d'un parent de s'allumer lorsqu'une ancre d'enfant est cliquée?

j'utilise actuellement jQuery pour rendre une div cliquable et dans cette div j'ai aussi des ancres. Le problème que je rencontre, c'est que lorsque je clique sur une ancre, les deux clics se déclenchent (pour la div et l'ancre). Comment puis-je empêcher l'événement onclick de la div de s'allumer 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>
261
demandé sur Jonathon Watney 2009-09-02 21:19:05

15 réponses

les Événements de la bulle au point le plus élevé dans les DOM au cours de laquelle 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 le div, chaque élément enfant du div afficherait son événement de clic dans le DOM jusqu'à ce que le gestionnaire D'événements de clic du DIV le rattrape.

il y a deux solutions à cela est de vérifier pour voir qui est réellement à 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énements de clic à vos liens qui leur disent de arrêter le bouillonnement d'événement après que leur propre gestionnaire exécute:

$("#clickable a").click(function(e) {
   // Do something
   e.stopPropagation();
});
363
répondu Rex M 2018-08-13 20:19:36

Utiliser stopPropagation la méthode, voir un exemple:

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

comme dit par jQuery Docs:

stopPropagation empêche l'événement de bouillonner le DOM arbre, empêchant tout parent gestionnaires informés de l'événement.

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

87
répondu Cleiton 2016-01-04 19:33:29

voici ma solution pour tout le monde là-bas à la recherche d'un code non-jQuery (pur javascript)

document.getElementById("clickable").addEventListener("click", function( e ){
    e = window.event || e; 
    if(this === e.target) {
        // put your code here
    }
});

votre code ne sera pas exécuté si cliqué sur les enfants du parent

36
répondu Sabaz 2015-04-07 18:53:19

vous pouvez également essayer ce

$("#clickable").click(function(event) {
   var senderElementName = event.target.tagName.toLowerCase();
   if(senderElementName === 'div')
   {
       // do something here 
   } 
   else
   {
      //do something with <a> tag
   }
});
11
répondu Rashad Annara 2015-08-16 10:50:46

en utilisant return false; ou e.stopPropogation(); ne permettra pas l'exécution d'autres codes. Il va arrêter le flux à ce point lui-même.

8
répondu Imamudin Naseem 2015-04-15 17:22:53

si vous avez plusieurs éléments dans le div cliquable, vous devez faire ceci:

$('#clickable *').click(function(e){ e.stopPropagation(); });
7
répondu Ivan Ivković 2012-08-11 10:15:32

si vous n'avez pas l'intention d'interagir avec l'élément ou les éléments intérieurs dans tous les cas, alors une solution CSS pourrait être utile pour vous.

il suffit de régler le/les élément (s) intérieur (s) à pointer-events: none

dans votre cas:

.clickable > a {
    pointer-events: none;
}

ou pour cibler tous les éléments intérieurs en général:

.clickable * {
    pointer-events: none;
}

Ce facile hack m'a sauvé beaucoup de temps, tout en développant avec ReactJS

La prise en charge du navigateur

peut être trouvée ici: http://caniuse.com/#feat=pointer-events

7
répondu Human Askari 2017-05-04 09:07:13

écrire si quelqu'un a besoin (travaillé pour moi):

event.stopImmediatePropagation()

à Partir de ce solution.

4
répondu Bahadir Tasdemir 2017-05-23 12:18:22

voici un exemple d'utilisation de L'angle 2+

par exemple, si vous voulez fermer un composant Modal si l'utilisateur clique en dehors de celui-ci:

// Close the modal if the document is clicked.

@HostListener('document:click', ['$event'])
public onDocumentClick(event: MouseEvent): void {
  this.closeModal();
}

// Don't close the modal if the modal itself is clicked.

@HostListener('click', ['$event'])
public onClick(event: MouseEvent): void {
  event.stopPropagation();
}
3
répondu Steve Brush 2017-08-25 18:16:49

vous devez empêcher l'événement d'atteindre le parent (le div). Voir la partie à propos de bubbling ici , et jQuery-information API spécifique ici .

1
répondu Matt Ball 2009-09-02 17:27:27

pour spécifier un sous-élément comme unclickable écrire la hiérarchie css comme dans l'exemple ci-dessous.

dans cet exemple, j'arrête la propagation à tout élément (*) à l'intérieur de td à l'intérieur de tr à l'intérieur d'un tableau avec la classe".sous-tableau 151920920"

$(document).ready(function()
{    
   $(".subtable tr td *").click(function (event)
   {
       event.stopPropagation();
   });

});
0
répondu user3202819 2014-01-16 14:18:09

au cas où quelqu'un aurait eu ce problème en utilisant React, c'est comme ça que je l'ai résolu.

scss:

#loginBackdrop {
position: absolute;
width: 100% !important;
height: 100% !important;
top:0px;
left:0px;
z-index: 9; }

#loginFrame {
width: $iFrameWidth;
height: $iFrameHeight;
background-color: $mainColor;
position: fixed;
z-index: 10;
top: 50%;
left: 50%;
margin-top: calc(-1 * #{$iFrameHeight} / 2);
margin-left: calc(-1 * #{$iFrameWidth} / 2);
border: solid 1px grey;
border-radius: 20px;
box-shadow: 0px 0px 90px #545454; }

Composant render():

render() {
    ...
    return (
        <div id='loginBackdrop' onClick={this.props.closeLogin}>
            <div id='loginFrame' onClick={(e)=>{e.preventDefault();e.stopPropagation()}}>
             ... [modal content] ...
            </div>
        </div>
    )
}

par l'ajout d'une fonction onClick pour les évènements de clic de souris modal (content div) de l'enfant sont empêchés d'atteindre la fonction 'closeLogin' de l'élément parent.

cela a fait le tour pour moi et j'ai pu créer un effet modal avec 2 divs simples.

0
répondu Claudio 2018-08-25 06:29:56

ajouter a comme suit:

<a href="http://foo.com" onclick="return false;">....</a>

ou return false; de gestionnaire d'événements click pour #clickable comme:

  $("#clickable").click(function() {
        var url = $("#clickable a").attr("href");
        window.location = url;
        return false;
   });
-3
répondu TheVillageIdiot 2009-09-02 17:27:20

toutes les solutions sont compliquées et de 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
répondu ratnesh 2012-01-01 22:12:29
<a onclick="return false;" href="http://foo.com">I want to ignore my parent's onclick event.</a>
-6
répondu andres descalzo 2009-09-02 17:25:13