Jak zatrzymać propagację zdarzeń za pomocą wbudowanego atrybutu onclick?


313

Rozważ następujące:

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

Jak mogę to zrobić, aby kliknięcie zakresu przez użytkownika nie uruchamiało divzdarzenia kliknięcia?

Odpowiedzi:


272

Użyj event.stopPropagation () .

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

Dla IE: window.event.cancelBubble = true

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

11
W FireFox nie ma czegoś takiego jak obiekt zdarzenia.
Robert C. Barth

6
Obiekt zdarzenia jest parametrem wywołania zwrotnego. W rzeczywistości nie ma czegoś takiego jak obiekt zdarzenia w IE, ponieważ obiekt ten jest dostępny przez window.event zamiast być parametrem funkcji :-)
Vincent Robert

66
Jest to po prostu złe - wbudowane moduły obsługi onclick nie otrzymują zdarzenia jako argumentu. Prawidłowe rozwiązanie to Gareths poniżej.
Benubird,

2
W przeglądarce Firefox można uzyskać dostęp do zdarzenia zmiennego w skrypcie wbudowanym, ale funkcja window.event nie jest dostępna. <div onclick = "alert (event);"> </div>
Morgan Cheng

1
eventWydaje się, że jest dostępny również podczas wydarzeń wbudowanych w IOS Safari.
Yuval A.

210

Istnieją dwa sposoby uzyskania obiektu zdarzenia z wnętrza funkcji:

  1. Pierwszy argument w przeglądarce zgodnej z W3C (Chrome, Firefox, Safari, IE9 +)
  2. Obiekt window.event w przeglądarce Internet Explorer (<= 8)

Jeśli potrzebujesz obsługi starszych przeglądarek, które nie postępują zgodnie z zaleceniami W3C, zazwyczaj wewnątrz funkcji możesz użyć czegoś takiego:

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

które sprawdzą najpierw jedną, a potem drugą i zapiszą dowolną znalezioną w zmiennej zdarzenia. Jednak w wbudowanym module obsługi zdarzeń nie ma eobiektu do użycia. W takim przypadku musisz skorzystać z argumentskolekcji, która jest zawsze dostępna i odnosi się do pełnego zestawu argumentów przekazanych do funkcji:

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

Jednak ogólnie rzecz biorąc, powinieneś unikać wbudowanych procedur obsługi zdarzeń, jeśli potrzebujesz skomplikowanych czynności, takich jak zatrzymanie propagacji. Osobne pisanie programów obsługi zdarzeń i dołączanie ich do elementów jest znacznie lepszym pomysłem w perspektywie średnio- i długoterminowej, zarówno pod względem czytelności, jak i łatwości konserwacji.


11
W odbiorniku wbudowanym można przekazać obiekt zdarzenia, taki jak:, onclick="foo(event)"a następnie w funkcji function foo(event){/* do stuff with event */}. Działa to zarówno w modelach zdarzeń IE, jak i W3C.
RobG,

5
To, że „mniejszy lub równy osiem” jest nieco… dwuznaczny.
TechNyquist,

8
to nie odpowiada na pytanie.
jcomeau_ictx

1
zgrabna odpowiedź na inne pytanie. : - /
Arel

80

Należy pamiętać, że window.event nie jest obsługiwany w FireFox, a zatem musi być coś w stylu:

e.cancelBubble = true

Lub możesz użyć standardu W3C dla FireFox:

e.stopPropagation();

Jeśli chcesz się podoba, możesz to zrobić:

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

    //IE9 & Other Browsers
    if (e.stopPropagation) {
      e.stopPropagation();
    }
    //IE8 and Lower
    else {
      e.cancelBubble = true;
    }
}

12
Aby to zadziałało, należy nazwać to tak:<div onclick="myEventHandler(event);">
DarkDust,

1
Może to być „event || window.event”.
Pointy

1
jeśli (e.cancelBubble) nie wygląda mi dobrze, ustaw ją na true, jeśli to już prawda
Guillaume86

e.cancelBubblezwraca false w IE! Nie może dojść do e.cancelBubble = true;instrukcji. Zamiast tego użyj warunku SoftwareARM !!
mauretto

45

Użyj tej funkcji, aby sprawdzić, czy istnieje poprawna metoda.

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

20

Miałem ten sam problem - pole błędu js w IE - działa tak dobrze we wszystkich przeglądarkach, o ile widzę (event.cancelBubble = true wykonuje pracę w IE)

onClick="if(event.stopPropagation){event.stopPropagation();}event.cancelBubble=true;"

1
Dzięki @MSC dokładnie to, czego potrzebowałem!
DannyC

1
Skrypt wewnętrzny. Odpowiada na pytanie
Cesar

10

To zadziałało dla mnie

<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>

Czy na pewno ten fragment kodu działał dla Ciebie? Ponieważ wygląda na to, że występuje problem cytowania ciągu w module obsługi onclick zewnętrznego div ...?!
Nicole,

7

W przypadku stron internetowych ASP.NET (nie MVC) można użyć Sys.UI.DomEventobiektu jako opakowania zdarzenia natywnego.

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

lub przekazać zdarzenie jako parametr do funkcji wewnętrznej:

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

oraz w niektórych funkcjach:

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


2

Nie mogę komentować z powodu Karmy, więc piszę to jako całą odpowiedź: Zgodnie z odpowiedzią Garetha (var e = argumenty [0] || window.event; [...]) Użyłem tego onelinera w wierszu po kliknięciu szybki hack:

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

Wiem, że jest późno, ale chciałem poinformować, że działa to w jednej linii. Nawiasy klamrowe zwracają zdarzenie, które ma w obu przypadkach funkcję stopPropagation, więc próbowałem zamknąć je w nawiasy klamrowe, jak w przypadku if i .... to działa. :)


1

Działa to również - w linku HTML użyj onclick ze zwrotem w następujący sposób:

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

A potem funkcja comfirmClick () powinna wyglądać następująco:

function confirmClick() {
    if(confirm("Do you really want to delete this task?")) {
        return true;
    } else {
        return false;
    }
};

2
To nie było znaczenie pytania.
jzonthemtn

@jbird Właśnie to oznaczało pytanie. Jest to inny (starszy) sposób anulowania zdarzenia niż bąbelkowanie drzewa dom (jest w specyfikacji poziomu 1 interfejsu API dom).
gion_13

@ gion_13 Ale akcja kliknięcia nie jest czymś, co użytkownik musi potwierdzić. W tym pytaniu chcemy tylko, aby uruchomił się onclick () dziecka, a nie onclick () rodzica. Umieszczenie monitu między nimi nie jest pomocne. Mam nadzieję, że widzisz tę różnicę.
jzonthemtn

1
To confirmnie jest istotne. Mam na myśli wartość zwracaną . cytat: W linku HTML użyj onclick z takim zwrotem
gion_13

zwracanie false anuluje po linku, nie anuluje propagacji na moim chrome
commonpike

1

Dlaczego nie sprawdzić, który element został kliknięty? Jeśli klikniesz na coś, window.event.targetzostanie przypisany do elementu, który został kliknięty, a kliknięty element można również przekazać jako argument.

Jeśli cel i element nie są sobie równe, rozprzestrzeniło się zdarzenie.

function myfunc(el){
  if (window.event.target === el){
      // perform action
  }
}
<div onclick="myfunc(this)" />

Dzięki kolego, to wydaje się być najczystszym rozwiązaniem tutaj. Na marginesie należy jednak wziąć pod uwagę, że pasuje to tylko wtedy, gdy kliknięty element jest rzeczywistym najwyższym elementem.
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>

0

Najlepszym rozwiązaniem byłoby obsłużyć zdarzenie za pomocą funkcji javascript, ale w celu użycia prostego i szybkiego rozwiązania wykorzystującego bezpośrednio element html, a gdy „event” i „window.event” są przestarzałe i nie są powszechnie obsługiwane ( https://developer.mozilla.org/en-US/docs/Web/API/Window/event ), sugeruję następujący „twardy kod”:

<div onclick="alert('blablabla'); (arguments[0] ? arguments[0].stopPropagation() : false);">...</div>
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.