Wie stoppe ich die Ereignisausbreitung mit dem Inline-Onclick-Attribut?

313

Folgendes berücksichtigen:

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

Wie kann ich festlegen, dass das Klickereignis des Benutzers nicht ausgelöst wird, wenn der Benutzer auf die Spanne divklickt?

Sam
quelle

Antworten:

272

Verwenden Sie event.stopPropagation () .

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

Für IE: window.event.cancelBubble = true

<span onclick="window.event.cancelBubble = true; alert('you clicked inside the header');">something inside the header</span>
James
quelle
11
In FireFox gibt es kein Ereignisobjekt.
Robert C. Barth
6
Das Ereignisobjekt ist ein Parameter des Rückrufs. Tatsächlich gibt es im IE kein Ereignisobjekt, da auf dieses Objekt über window.event zugegriffen werden kann, anstatt ein Parameter der Funktion zu sein :-)
Vincent Robert
66
Dies ist einfach falsch - Inline-Onclick-Handler erhalten das Ereignis nicht als Argument übergeben. Die richtige Lösung ist Gareths unten.
Benubird
2
In Firefox können Sie im Inline-Skript auf ein variables Ereignis zugreifen, aber window.event ist nicht verfügbar. <div onclick = "alert (event);"> </ div>
Morgan Cheng
1
eventscheint auch in Inline-Events in IOS Safari verfügbar zu sein.
Yuval A.
210

Es gibt zwei Möglichkeiten, das Ereignisobjekt aus einer Funktion heraus abzurufen:

  1. Das erste Argument in einem W3C-kompatiblen Browser (Chrome, Firefox, Safari, IE9 +)
  2. Das window.event-Objekt in Internet Explorer (<= 8)

Wenn Sie ältere Browser unterstützen müssen, die nicht den W3C-Empfehlungen entsprechen, würden Sie im Allgemeinen innerhalb einer Funktion Folgendes verwenden:

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

Das würde zuerst das eine und dann das andere prüfen und speichern, was auch immer in der Ereignisvariablen gefunden wurde. In einem Inline-Event-Handler gibt es jedoch keinene Objekt zu verwenden. In diesem Fall müssen Sie die argumentsSammlung nutzen, die immer verfügbar ist und sich auf den vollständigen Satz von Argumenten bezieht, die an eine Funktion übergeben wurden:

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

Im Allgemeinen sollten Sie jedoch Inline-Ereignishandler vermeiden, wenn Sie etwas Kompliziertes wie das Stoppen der Weitergabe benötigen. Es ist mittel- und langfristig eine viel bessere Idee, Ihre Event-Handler separat zu schreiben und sie an Elemente anzuhängen, sowohl aus Gründen der Lesbarkeit als auch der Wartbarkeit.

Gareth
quelle
11
Von einem Inline-Listener aus können Sie das Ereignisobjekt wie folgt übergeben: onclick="foo(event)"und dann in der Funktion function foo(event){/* do stuff with event */}. Dies funktioniert sowohl in IE- als auch in W3C-Ereignismodellen.
RobG
5
Das "kleiner oder gleich acht" ist etwas ... mehrdeutig.
TechNyquist
8
Dies beantwortet die Frage nicht wirklich.
jcomeau_ictx
1
nette Antwort auf eine andere Frage. : - /
Arel
80

Beachten Sie, dass window.event in FireFox nicht unterstützt wird. Daher muss es sich um Folgendes handeln:

e.cancelBubble = true

Oder Sie können den W3C-Standard für FireFox verwenden:

e.stopPropagation();

Wenn Sie Lust haben, können Sie dies tun:

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
quelle
12
Und damit es funktioniert, muss man das so nennen:<div onclick="myEventHandler(event);">
DarkDust
1
Es könnte "event || window.event" sein.
Pointy
1
Wenn (e.cancelBubble) für mich nicht richtig aussieht, setzen Sie es auf true, wenn es bereits wahr ist
Guillaume86
e.cancelBubblegibt im IE false zurück! Es kann die e.cancelBubble = true;Anweisung nicht erreichen . Verwenden Sie stattdessen den Zustand von SoftwareARM !!
Mauretto
45

Verwenden Sie diese Funktion, um festzustellen, ob die richtige Methode vorhanden ist.

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

Ich hatte das gleiche Problem - js Fehlerbox im IE - dies funktioniert in allen Browsern, soweit ich sehen kann (event.cancelBubble = true erledigt den Job im IE)

onClick="if(event.stopPropagation){event.stopPropagation();}event.cancelBubble=true;"
MSC
quelle
1
Danke @MSC genau das, was ich brauchte!
DannyC
1
Inline-Skript. Es beantwortet die Frage
Cesar
10

Das hat bei mir funktioniert

<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
quelle
Sind Sie sicher, dass genau dieses Code-Snippet für Sie funktioniert hat? Weil es so aussieht, als ob es im Onclick-Handler des äußeren Divs ein Problem mit Anführungszeichen gibt ...?!
Nicole
7

Für ASP.NET-Webseiten (nicht MVC) können Sie das Sys.UI.DomEventObjekt als Wrapper für native Ereignisse verwenden.

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

oder übergeben Sie das Ereignis als Parameter an die innere Funktion:

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

und in irgendeiner Funktion:

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

Laut dieser Seite benötigen Sie im IE:

event.cancelBubble = true

ajh1138
quelle
2

Ich kann wegen Karma keinen Kommentar abgeben, also schreibe ich dies als ganze Antwort: Gemäß der Antwort von Gareth (var e = Argumente [0] || window.event; [...]) habe ich diesen Oneliner inline auf dem Onclick für a verwendet schneller Hack:

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

Ich weiß, dass es spät ist, aber ich wollte Sie wissen lassen, dass dies in einer Zeile funktioniert. Die geschweiften Klammern geben ein Ereignis zurück, an das in beiden Fällen die stopPropagation-Funktion angehängt ist. Deshalb habe ich versucht, sie in geschweiften Klammern zu kapseln, wie in einem if und .... es funktioniert. :) :)

user3611941
quelle
1

Dies funktioniert auch - Verwenden Sie im Link-HTML onclick mit der folgenden Rückgabe:

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

Und dann sollte die Funktion comfirmClick () wie folgt aussehen:

function confirmClick() {
    if(confirm("Do you really want to delete this task?")) {
        return true;
    } else {
        return false;
    }
};
Rajendra
quelle
2
Dies ist nicht das, was die Frage bedeutete.
jzonthemtn
@jbird Genau das bedeutete die Frage. Es ist eine andere (ältere) Methode, ein Ereignis vom Sprudeln des Dom-Baums abzubrechen (in den Spezifikationen der Dom-API-Ebene 1).
gion_13
@ gion_13 Die Aktion des Klicks muss der Benutzer jedoch nicht bestätigen. In der Frage möchten wir nur, dass der onclick () des Kindes ausgelöst wird und nicht der onclick () des Elternteils. Es ist nicht hilfreich, eine Benutzeraufforderung dazwischen zu setzen. Ich hoffe, Sie können diesen Unterschied sehen.
jzonthemtn
1
Das confirmist nicht relevant. Ich beziehe mich auf den Rückgabewert . Zitat: In dem Link HTML verwenden Sie onclick mit Rückkehr wie
folgt
Wenn Sie nach dem Link falsche Abbrüche zurückgeben, wird die Weitergabe auf meinem Chrome
Commonpike am
1

Warum nicht einfach überprüfen, auf welches Element geklickt wurde? Wenn Sie auf etwas klicken, window.event.targetwird dem Element, auf das geklickt wurde, und zugewiesen das angeklickte Element kann auch als Argument übergeben werden.

Wenn das Ziel und das Element nicht gleich sind, hat sich dieses Ereignis verbreitet.

function myfunc(el){
  if (window.event.target === el){
      // perform action
  }
}
<div onclick="myfunc(this)" />
cs01
quelle
Danke Kumpel, dies scheint hier die sauberste Lösung zu sein. Als Randnotiz müssen Sie jedoch berücksichtigen, dass dies nur übereinstimmt, wenn das angeklickte Element das tatsächlich oberste Element ist.
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>
Commonpike
quelle
0

Die beste Lösung wäre, mit dem Ereignis über eine Javascript-Funktion umzugehen, aber um eine einfache und schnelle Lösung mit dem HTML-Element direkt zu verwenden, und sobald "event" und "window.event" veraltet sind und nicht allgemein unterstützt werden ( https://developer.mozilla.org/en-US/docs/Web/API/Window/event ) schlage ich den folgenden "harten Code" vor:

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