Obsługa zdarzeń pola wyboru jQuery

136

Mam:

<form id="myform">
   <input type="checkbox" name="check1" value="check1">
   <input type="checkbox" name="check2" value="check2">
</form>

Jak używać jQuery do przechwytywania dowolnego zdarzenia czekania występującego w myformi określania, które pole wyboru zostało przełączone (i wiedzieć, czy zostało włączone, czy wyłączone)?

aeq
źródło

Odpowiedzi:

244
$('#myform :checkbox').change(function() {
    // this will contain a reference to the checkbox   
    if (this.checked) {
        // the checkbox is now checked 
    } else {
        // the checkbox is now no longer checked
    }
});
Darin Dimitrov
źródło
30
thisjest już ustawiony na element DOM pola wyboru, więc this.checkedjest wystarczający. Nie będziesz musiał tworzyć dla niego kolejnego obiektu jQuery, chyba że planujesz nim manipulować.
Walf
18
Tylko mała wskazówka. Uzyskasz wzrost wydajności, używając input: checkbox w swoim selektorze zamiast po prostu: checkbox, ponieważ to drugie jest tłumaczone na uniwersalny selektor *: checkbox.
jimmystormig
23
Kliknięcie nie jest w pobliżu żadnego zdarzenia czekowego.
Peter,
27
To nie jest najlepsza odpowiedź. Jeśli masz odpowiednią etykietę dla swojego wejścia (np. <label for='myInput'>Checkbox:</label><input id='myInput' name='myInput' type='checkbox'/>) I klikniesz tę etykietę, pole wyboru zostanie zaznaczone, ale ta funkcja NIE zostanie wywołana. Powinieneś skorzystać z .change()wydarzenia
Patrick
7
Ta odpowiedź nie daje pełnej odpowiedzi - proszę zapoznać się z odpowiedzią Anuraga poniżej, która jest ZNACZNIE bardziej kompletną (i dokładną) odpowiedzią. Ta odpowiedź jest oczywiście częściowo poprawna, ale jak stwierdzono, nie jest to najlepsza odpowiedź.
Carnix,
131

Użyj zdarzenia zmiany.

$('#myform :checkbox').change(function() {
    // this represents the checkbox that was checked
    // do something with it
});
Anurag
źródło
5
Jeśli pole wyboru jest ukryte, użytkownik nie będzie mógł z nim wchodzić. Daj mi znać, jeśli miałeś na myśli coś innego.
Anurag
1
To nie działa $("input[name=check1]").prop('checked', true). Zobacz jsfiddle.net/Z3E8V/2
Peter,
15
To jest zgodne z projektem. Programowa zmiana właściwości elementu DOM nie wyzwala powiązanych procedur obsługi zdarzeń. Będziesz musiał strzelać z nich ręcznie.
Anurag
6
To powinna być wybrana odpowiedź, obejmuje kliknięcie etykiety pola wyboru
Patrick
3
Z dokumentacji jQuery: „Ponieważ :checkboxjest to rozszerzenie jQuery i nie jest częścią specyfikacji CSS, zapytania używające :checkboxnie mogą korzystać ze zwiększenia wydajności zapewnianego przez natywną querySelectorAll()metodę DOM . Aby uzyskać lepszą wydajność w nowoczesnych przeglądarkach, użyj [type="checkbox"]zamiast tego”.
NXT
54

Istnieje kilka przydatnych odpowiedzi, ale żadna nie wydaje się obejmować wszystkich najnowszych opcji. W tym celu wszystkie moje przykłady uwzględniają również obecność pasujących labelelementów, a także pozwalają dynamicznie dodawać pola wyboru i wyświetlać wyniki w panelu bocznym (poprzez przekierowanie console.log).

  • Nasłuchiwanie clickzdarzeń na checkboxesto nie dobry pomysł, jako że nie pozwoli na klawiatury toggle lub zmian dokonanych w którym dopasowanie labelelement został kliknięty. Zawsze nasłuchuj changewydarzenia.

  • :checkboxZamiast tego użyj pseudo-selektora jQuery input[type=checkbox]. :checkboxjest krótszy i bardziej czytelny.

  • Użyj is()z :checkedpseudo-selektorem jQuery , aby sprawdzić, czy pole wyboru jest zaznaczone. Gwarantuje to działanie we wszystkich przeglądarkach.

Podstawowa obsługa zdarzeń dołączona do istniejących elementów:

$('#myform :checkbox').change(function () {
    if ($(this).is(':checked')) {
        console.log($(this).val() + ' is now checked');
    } else {
        console.log($(this).val() + ' is now unchecked');
    }
});

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/2/

Uwagi:

  • Używa :checkboxselektora, który jest lepszy niż używanieinput[type=checkbox]
  • To łączy się tylko z pasującymi elementami, które istnieją w momencie zarejestrowania zdarzenia.

Delegowana procedura obsługi zdarzeń dołączona do elementu ancestor:

Programy obsługi zdarzeń delegowanych są przeznaczone do sytuacji, w których elementy mogą jeszcze nie istnieć (ładowane dynamicznie lub utworzone) i są bardzo przydatne. Oni delegować odpowiedzialność elementu przodka (stąd nazwa).

$('#myform').on('change', ':checkbox', function () {
    if ($(this).is(':checked')) {
        console.log($(this).val() + ' is now checked');
    } else {
        console.log($(this).val() + ' is now unchecked');
    }
});

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/4/

Uwagi:

  • Działa to poprzez nasłuchiwanie zdarzeń (w tym przypadku change ), które przechodzą do niezmiennego elementu nadrzędnego (w tym przypadku #myform).
  • To wtedy stosuje się selektor jQuery ( ':checkbox'w tym przypadku) tylko do elementów w łańcuchu bąbelkowej .
  • To to stosuje się funkcję obsługi zdarzeń do tylko tych elementów, które spowodowały pasujące zdarzenie.
  • Posługiwać się document jako domyślnego, aby połączyć delegowaną procedurę obsługi zdarzeń, jeśli nic innego nie jest bliższe / wygodne.
  • Nie używaj bodydo dołączania delegowanych zdarzeń, ponieważ ma to błąd (związany ze stylizacją), który może uniemożliwić mu otrzymywanie zdarzeń myszy.

Efektem delegowanych programów obsługi jest to, że pasujące elementy muszą istnieć tylko w czasie zdarzenia, a nie w momencie zarejestrowania procedury obsługi zdarzeń. Pozwala to na dynamicznie dodawane treści w celu generowania zdarzeń.

P: czy jest wolniejszy?

Odp .: Dopóki zdarzenia są z szybkością interakcji z użytkownikiem, nie musisz się martwić o znikomą różnicę w szybkości między delegowaną obsługą zdarzeń a bezpośrednio połączoną procedurą obsługi. Korzyści z delegowania znacznie przewyższają wszelkie drobne wady. Rejestrowanie delegowanych programów obsługi zdarzeń jest w rzeczywistości szybsze ponieważ zazwyczaj łączą się z pojedynczym pasującym elementem.


Dlaczego nie prop('checked', true)odpalichange wydarzenia?

Jest to faktycznie zgodne z projektem. Gdyby to wywołało wydarzenie, łatwo znalazłbyś się w sytuacji niekończących się aktualizacji. Zamiast tego po zmianie zaznaczonej właściwości wyślij zdarzenie zmiany do tego samego elementu za pomocą trigger(nie triggerHandler):

np. bez triggerżadnego zdarzenia

$cb.prop('checked', !$cb.prop('checked'));

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/5/

np. z triggernormalnym zdarzeniem zmiany

$cb.prop('checked', !$cb.prop('checked')).trigger('change');

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/6/

Uwagi:

  • Nie używaj triggerHandlerzgodnie z sugestią jednego użytkownika, ponieważ nie spowoduje to wysłania zdarzeń do delegowanej procedury obsługi zdarzeń.

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/8/

chociaż będzie działać dla obsługi zdarzeń bezpośrednio połączonych z elementem:

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/9/

Zdarzenia wyzwalane przez .triggerHandler () nie zwiększają hierarchii DOM; jeśli nie są obsługiwane bezpośrednio przez element docelowy, nic nie robią.

Źródła: http://api.jquery.com/triggerhandler/

Jeśli ktoś ma dodatkowe funkcje, które według niego nie są objęte tym zakresem, prosimy o zaproponowanie dodatków .

Gone Coding
źródło
31

Korzystanie z nowej metody „on” w jQuery (1.7): http://api.jquery.com/on/

    $('#myform').on('change', 'input[type=checkbox]', function(e) {
        console.log(this.name+' '+this.value+' '+this.checked);

    });
  • program obsługi zdarzeń będzie działał
  • przechwyci, jeśli pole wyboru zostało zmienione za pomocą klawiatury, a nie tylko kliknięciem
Allen Hamilton
źródło
1
To nie działa $("input[name=check1]").prop('checked', true). Zobacz jsfiddle.net/Z3E8V/2
Peter,
7
Po prostu dodaj .triggerHandler('change');po .proprozmowie. Następnie przełączy pole ORAZ wywoła zdarzenie.
Hanna
5
$('#myform input:checkbox').click(
 function(e){
   alert($(this).is(':checked'))
 }
)
Myśliciel
źródło
val()nie mówi ci, czy tak checkedjest true.
Walf
5

Mając na uwadze fakt, że pytający specjalnie zażądał jQuery i że wybrana odpowiedź jest poprawna, należy zauważyć, że ten problem w rzeczywistości nie wymaga jQuery per say. Jeśli ktoś chce rozwiązać ten problem bez tego, może po prostu ustawićonClick atrybuty pól wyboru, do których chce dodać dodatkową funkcjonalność, na przykład:

HTML:

<form id="myform">
  <input type="checkbox" name="check1" value="check1" onClick="cbChanged(this);">
  <input type="checkbox" name="check2" value="check2" onClick="cbChanged(this);">
</form>

javascript:

function cbChanged(checkboxElem) {
  if (checkboxElem.checked) {
    // Do something special
  } else {
    // Do something else
  }
}

Skrzypce: http://jsfiddle.net/Y9f66/1/

Chase Sandmann
źródło
5
Umieszczanie programów obsługi zdarzeń bezpośrednio w HTML działa oczywiście. Jest to jednak w bezpośrednim konflikcie z metodologiami DRY i progresywnego ulepszania. Dokładniejsza odpowiedź brzmiałaby: „Nie potrzebujesz jQuery do dodawania programów obsługi zdarzeń” i zamiast tego użyj standardowego JS do dołączenia modułów obsługi kliknięć w osobnym pliku JS, zamiast umieszczać atrybuty onclick w kodzie HTML. Takie postępowanie „działa”, ale dobra praktyka kodowania nakazuje unikać tego, gdy jest to możliwe (co jest prawie zawsze w tym momencie, chyba że musisz wspierać IE6 lub coś, co nawet MS mówi, że nie powinieneś już robić)
Carnix
3

Wypróbowałem kod z pierwszej odpowiedzi, nie działa, ale mam zabawę i ta praca dla mnie

$('#vip').change(function(){
    if ($(this).is(':checked')) {
        alert('checked');
    } else {
        alert('uncheck');
    }
});
Somwang Souksavatd
źródło