Jak zatrzymać propagację zdarzeń po kliknięciu pola wyboru

182

Mam pole wyboru, które chcę wykonać akcję Ajax na zdarzeniu kliknięcia, jednak pole wyboru znajduje się również w kontenerze z własnym zachowaniem kliknięcia, którego nie chcę uruchamiać po kliknięciu tego pola wyboru. Ten przykład ilustruje to, co chcę zrobić:

$(document).ready(function() {
  $('#container').addClass('hidden');
  $('#header').click(function() {
    if ($('#container').hasClass('hidden')) {
      $('#container').removeClass('hidden');
    } else {
      $('#container').addClass('hidden');
    }
  });
  $('#header input[type=checkbox]').click(function(event) {
    // Do something
  });
});
#container.hidden #body {
  display: none;
}
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<div id="container">
  <div id="header">
    <h1>Title</h1>
    <input type="checkbox" name="test" />
  </div>
  <div id="body">
    <p>Some content</p>
  </div>
</div>

Nie mogę jednak wymyślić, jak zatrzymać propagację zdarzenia bez spowodowania, że ​​domyślne zachowanie kliknięcia (pole wyboru zostanie zaznaczone / odznaczone) nie zostanie uruchomione.

Oba poniższe elementy zatrzymują propagację zdarzeń, ale również nie zmieniają stanu pola wyboru:

event.preventDefault();
return false;
roryf
źródło
2
Znalazłem artykuł na ten temat, który może być pomocny dla innych stosów kwiatów. Szybka wskazówka: kliknij wiersz tabeli, aby uruchomić kliknięcie pola wyboru
Peder Rice,

Odpowiedzi:

341

zastąpić

event.preventDefault();
return false;

z

event.stopPropagation();

event.stopPropagation ()

Zatrzymuje propagowanie zdarzenia do elementów nadrzędnych, zapobiegając powiadamianiu o zdarzeniu przez wszystkie procedury nadrzędne.

event.preventDefault ()

Uniemożliwia przeglądarce wykonanie domyślnej akcji. Użyj metody isDefaultPrevented, aby dowiedzieć się, czy ta metoda została kiedykolwiek wywołana (dla tego obiektu zdarzenia).

Rahul
źródło
4
z jakiegoś powodu to nie działa dla mnie, ale zwrócił false.
Randy L
3
Jeśli wiążesz zdarzenie przy użyciu .live()metody, to nie zadziała. Będziesz musiał użyć return false;samego siebie.
rahul
2
Działa to przy użyciu .on()metody jQuery (funkcja live jest teraz przestarzała). Nie mogłem zrozumieć, dlaczego return false nie działa.
styfle
spędziłem sporo czasu, aby dowiedzieć się o tym zdarzeniu. preventDefault () nie pokazywał znacznika wyboru w IE8, ale działał dobrze w innych przeglądarkach. Znalazłem tę odpowiedź po tym, jak naprawiłem, a następnie googling przy pomocy słowa kluczowego preventDefault, IE8, przyniósł mnie tutaj.
signonsridhar
nie działał dla .. ale ta linia działała (bez zwracania wartości false) -> event.preventDefault (); event.stopPropagation ();
Kugan Kumar
32

Użyj metody stopPropagation:

event.stopPropagation();
Patrice Neff
źródło
29

Nie zapomnij o IE:

if (event.stopPropagation) {    // standard
        event.stopPropagation();
    } else {    // IE6-8
        event.cancelBubble = true;
}
Faraz Kelhini
źródło
23
Ta odpowiedź pochodzi z 2012 roku. W 2015 roku zapomnij o IE.
Taylan,
8
Dotyczy to również IE9. Moja maszyna testowa IE9 dusi się przy stopPropagation (), ale lubi cancelBubble (). Niestety, niektóre osoby / organizacje nadal używają IE9 w 2016 roku. Ci z nas, którzy mają klientów korporacyjnych, nie mogą tego zignorować.
Chris Cober,
uwielbiam ie5 w 2019 r.
SuperUberDuper
5

Jak wspomnieli inni, spróbuj stopPropagation().

Do wypróbowania jest drugi moduł obsługi: event.cancelBubble = true;jest to moduł obsługi specyficzny dla IE, ale jest obsługiwany przynajmniej w FF. Naprawdę niewiele o nim wiem, bo sam go nie użyłem, ale może warto spróbować, jeśli wszystko inne zawiedzie.

peirix
źródło
5

To doskonały przykład zrozumienia koncepcji propagacji zdarzeń. W oparciu o powyższe odpowiedzi końcowy kod będzie wyglądał jak wspomniano poniżej. Gdy użytkownik kliknie pole wyboru, propagacja zdarzeń do elementu nadrzędnego „nagłówek” zostanie zatrzymana event.stopPropagation();.

$(document).ready(function() {
            $('#container').addClass('hidden');
            $('#header').click(function() {
                if($('#container').hasClass('hidden')) {
                    $('#container').removeClass('hidden');
                } else {
                    $('#container').addClass('hidden');
                }
            });
          $('#header input[type=checkbox]').click(function(event) {
              if (event.stopPropagation) {    // standard
                   event.stopPropagation();
               } else {    // IE6-8
                    event.cancelBubble = true;
               }
          });     
  });
mehras
źródło
5

Podczas korzystania z jQuery nie trzeba osobno wywoływać funkcji zatrzymania.

Możesz po prostu wrócić falsew module obsługi zdarzeń

To zatrzyma wydarzenie i anuluje propagację.

Zobacz także event.preventDefault () vs. return false

Z dokumentów jQuery:

Te procedury obsługi mogą zatem uniemożliwiać delegowanie procedury obsługi przez wywołanie event.stopPropagation()lub powrót false.

DutchKevv
źródło
1

Kredyt dla @mehras kodu. Właśnie stworzyłem fragment kodu, aby to zademonstrować, ponieważ myślałem, że będzie to mile widziane i chciałem wymówki, by wypróbować tę funkcję.

$(document).ready(function() {
  $('#container').addClass('hidden');
  $('#header').click(function() {
    if ($('#container').hasClass('hidden')) {
      $('#container').removeClass('hidden');
    } else {
      $('#container').addClass('hidden');
    }
  });
  $('#header input[type=checkbox]').click(function(event) {
    if (event.stopPropagation) { // standard
      event.stopPropagation();
    } else { // IE6-8
      event.cancelBubble = true;
    }
  });
});
div {
  text-align: center;
  padding: 2em;
  font-size: 1.2em
}

.hidden {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="header"><input type="checkbox" />Checkbox won't bubble the event, but this text will.</div>
<div id="container">click() bubbled up!</div>

użytkownik2503764
źródło
Kod, który faktycznie pokazuje, jak używać zmiennej zdarzenia, dzięki.
Moshe Binieli
-1

W angularjs powinno to działać:

event.preventDefault(); 
event.stopPropagation();
Kugan Kumar
źródło