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é:
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>
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();
});
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.
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
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
}
});
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.
si vous avez plusieurs éléments dans le div cliquable, vous devez faire ceci:
$('#clickable *').click(function(e){ e.stopPropagation(); });
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 navigateurpeut être trouvée ici: http://caniuse.com/#feat=pointer-events
écrire si quelqu'un a besoin (travaillé pour moi):
event.stopImmediatePropagation()
à Partir de ce solution.
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();
}
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();
});
});
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.
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;
});
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
}
<a onclick="return false;" href="http://foo.com">I want to ignore my parent's onclick event.</a>