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?

Sam
źródło

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>
James
źródło
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.

Gareth
źródło
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;
    }
}
Robert C. Barth
źródło
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;
   }
}
SoftwareARM
źródło
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;"
MSC
źródło
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>
Matías Contreras Selman
źródło
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
}
Evgeny Gorb
źródło
5

Zgodnie z tą stroną w IE potrzebujesz:

event.cancelBubble = true

ajh1138
źródło
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. :)

użytkownik3611941
źródło
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;
    }
};
Rajendra
źródło
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)" />
cs01
źródło
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>
pospolity
źródło
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>
jose.serapicos
źródło