Comment arrêter la propagation des événements avec l'attribut onclick en ligne?

313

Considérer ce qui suit:

<div onclick="alert('you clicked the header')" class="header">
  <span onclick="alert('you clicked inside the header');">something inside the header</span>
</div>

Comment puis-je faire en sorte que lorsque l'utilisateur clique sur la plage, il ne déclenche pas l' divévénement de clic?

Sam
la source

Réponses:

272

Utilisez event.stopPropagation () .

<span onclick="event.stopPropagation(); alert('you clicked inside the header');">something inside the header</span>

Pour IE: window.event.cancelBubble = true

<span onclick="window.event.cancelBubble = true; alert('you clicked inside the header');">something inside the header</span>
James
la source
11
Il n'y a pas d'objet événement dans FireFox.
Robert C.Barth
6
L'objet événement est un paramètre du rappel. En fait, il n'y a pas d'objet événement dans IE car cet objet est accessible via window.event au lieu d'être un paramètre de la fonction :-)
Vincent Robert
66
C'est tout simplement faux - les gestionnaires onclick en ligne n'obtiennent pas l'événement comme argument. La solution correcte est Gareths, ci-dessous.
Benubird
2
Dans Firefox, vous pouvez avoir accès à un événement variable dans un script en ligne, mais window.event n'est pas disponible. <div onclick = "alert (event);"> </div>
Morgan Cheng
1
eventsemble également être disponible dans les événements en ligne dans IOS Safari.
Yuval A.
210

Il existe deux façons d'obtenir l'objet événement de l'intérieur d'une fonction:

  1. Le premier argument, dans un navigateur compatible W3C (Chrome, Firefox, Safari, IE9 +)
  2. L'objet window.event dans Internet Explorer (<= 8)

Si vous devez prendre en charge les navigateurs hérités qui ne suivent pas les recommandations du W3C, généralement à l'intérieur d'une fonction, vous utiliserez quelque chose comme ceci:

function(e) {
  var event = e || window.event;
  [...];
}

qui vérifierait d'abord l'un, puis l'autre et stocker celui qui a été trouvé dans la variable d'événement. Cependant, dans un gestionnaire d'événements en ligne, il n'y a pas d' eobjet à utiliser. Dans ce cas, vous devez profiter de la argumentscollection qui est toujours disponible et fait référence à l'ensemble complet des arguments passés à une fonction:

onclick="var event = arguments[0] || window.event; [...]"

Cependant, en règle générale, vous devez éviter les gestionnaires d'événements en ligne si vous avez besoin de quelque chose de compliqué comme l'arrêt de la propagation. Écrire vos gestionnaires d'événements séparément et les attacher à des éléments est une bien meilleure idée à moyen et long terme, à la fois pour la lisibilité et la maintenabilité.

Gareth
la source
11
À partir d'un écouteur en ligne, vous pouvez passer l'objet événement comme:, onclick="foo(event)"puis dans la fonction function foo(event){/* do stuff with event */}. Cela fonctionne à la fois dans les modèles d'événements IE et W3C.
RobG
5
Ce "moindre ou égal à huit" est quelque peu ... ambigu.
TechNyquist
8
cela ne répond pas vraiment à la question.
jcomeau_ictx
1
réponse soignée à une question différente. : - /
Arel
80

Gardez à l'esprit que window.event n'est pas pris en charge dans FireFox, et qu'il doit donc s'agir de quelque chose comme:

e.cancelBubble = true

Ou, vous pouvez utiliser la norme W3C pour FireFox:

e.stopPropagation();

Si vous voulez devenir chic, vous pouvez le faire:

function myEventHandler(e)
{
    if (!e)
      e = window.event;

    //IE9 & Other Browsers
    if (e.stopPropagation) {
      e.stopPropagation();
    }
    //IE8 and Lower
    else {
      e.cancelBubble = true;
    }
}
Robert C. Barth
la source
12
Et pour le faire fonctionner, il faut appeler cela comme ceci:<div onclick="myEventHandler(event);">
DarkDust
1
Il peut s'agir de "event || window.event".
Pointy
1
si (e.cancelBubble) ne me semble pas correct, vous le définissez sur true si c'est déjà vrai
Guillaume86
e.cancelBubblerenvoie faux dans IE! Il ne peut pas atteindre l' e.cancelBubble = true;instruction. Utilisez plutôt l'état de SoftwareARM !!
mauretto
45

Utilisez cette fonction, elle testera l'existence de la bonne méthode.

function disabledEventPropagation(event)
{
   if (event.stopPropagation){
       event.stopPropagation();
   }
   else if(window.event){
      window.event.cancelBubble=true;
   }
}
SoftwareARM
la source
20

J'ai eu le même problème - boîte d'erreur js dans IE - cela fonctionne très bien dans tous les navigateurs pour autant que je puisse voir (event.cancelBubble = true fait le travail dans IE)

onClick="if(event.stopPropagation){event.stopPropagation();}event.cancelBubble=true;"
MSC
la source
1
Merci @MSC exactement ce dont j'avais besoin!
DannyC
1
Script en ligne. Cela répond à la question
Cesar
10

Cela a fonctionné pour moi

<script>
function cancelBubble(e) {
 var evt = e ? e:window.event;
 if (evt.stopPropagation)    evt.stopPropagation();
 if (evt.cancelBubble!=null) evt.cancelBubble = true;
}
</script>

<div onclick="alert('Click!')">
  <div onclick="cancelBubble(event)">Something inside the other div</div>
</div>
Matías Contreras Selman
la source
Êtes-vous sûr que cet extrait de code exact a fonctionné pour vous? Parce qu'il semble qu'il y ait un problème de citation de chaîne dans le gestionnaire onclick du div externe ...?!
Nicole
7

Pour les pages Web ASP.NET (pas MVC), vous pouvez utiliser l' Sys.UI.DomEventobjet comme wrapper d'événement natif.

<div onclick="event.stopPropagation();" ...

ou, passez l'événement comme paramètre à la fonction interne:

<div onclick="someFunction(event);" ...

et dans certains Fonction:

function someFunction(event){
    event.stopPropagation(); // here Sys.UI.DomEvent.stopPropagation() method is used
    // other onclick logic
}
Evgeny Gorb
la source
5

Selon cette page , dans IE, vous avez besoin de:

event.cancelBubble = true

ajh1138
la source
2

Je ne peux pas commenter à cause de Karma, donc j'écris ceci comme une réponse entière: selon la réponse de Gareth (var e = arguments [0] || window.event; [...]), j'ai utilisé cette ligne en ligne sur le onclick pour un piratage rapide:

<div onclick="(arguments[0] || window.event).stopPropagation();">..</div>

Je sais qu'il est tard mais je voulais vous faire savoir que cela fonctionne sur une seule ligne. Les accolades renvoient un événement auquel la fonction stopPropagation est attachée dans les deux cas, j'ai donc essayé de les encapsuler entre accolades comme dans un if et .... cela fonctionne. :)

user3611941
la source
1

Cela fonctionne également - Dans le lien HTML, utilisez onclick avec return comme ceci:

<a href="mypage.html" onclick="return confirmClick();">Delete</a>

Et puis la fonction comfirmClick () devrait être comme:

function confirmClick() {
    if(confirm("Do you really want to delete this task?")) {
        return true;
    } else {
        return false;
    }
};
Rajendra
la source
2
Ce n'est pas ce que la question voulait dire.
jzonthemtn
@jbird C'est exactement ce que la question voulait dire. C'est une manière différente (plus ancienne) d'annuler un événement de bouillonner dans l'arbre dom (c'est dans les spécifications dom api niveau 1).
gion_13
@ gion_13 Mais l'action du clic n'est pas quelque chose que l'utilisateur doit confirmer. Dans la question, nous voulons seulement que le onclick () de l'enfant se déclenche et non le onclick () du parent. Mettre une invite utilisateur entre ceux-ci n'est pas utile. J'espère que vous pouvez voir cette différence.
jzonthemtn
1
Le confirmn'est pas pertinent. Je fais référence à la valeur de retour . citation: Dans le lien HTML, utilisez onclick avec retour comme celui-ci
gion_13
renvoyer de faux annulations en suivant le lien, il n'annule pas la propagation sur mon chrome
commonpike
1

Pourquoi ne pas simplement vérifier quel élément a été cliqué? Si vous cliquez sur quelque chose, window.event.targetest affecté à l'élément sur lequel vous avez cliqué, et l'élément cliqué peut également être passé en argument.

Si la cible et l'élément ne sont pas égaux, c'est un événement qui s'est propagé.

function myfunc(el){
  if (window.event.target === el){
      // perform action
  }
}
<div onclick="myfunc(this)" />
cs01
la source
Merci mon pote, cela semble être la solution la plus propre ici. Sur une note latérale, vous devez cependant considérer que cela ne correspond que lorsque l'élément cliqué est l'élément le plus haut réel.
Simon Mattes
0
<div onclick="alert('you clicked the header')" class="header">
  <span onclick="alert('you clicked inside the header'); event.stopPropagation()">
    something inside the header
  </span>
</div>
pic commun
la source
0

La meilleure solution serait de gérer l'événement via une fonction javascript, mais afin d'utiliser une solution simple et rapide en utilisant directement l'élément html, et une fois que "event" et "window.event" sont obsolètes et ne sont pas universellement pris en charge ( https://developer.mozilla.org/en-US/docs/Web/API/Window/event ), je suggère le "code dur" suivant:

<div onclick="alert('blablabla'); (arguments[0] ? arguments[0].stopPropagation() : false);">...</div>
jose.serapicos
la source