Penanganan peristiwa kotak centang jQuery

138

Saya memiliki yang berikut ini:

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

Bagaimana cara menggunakan jQuery untuk menangkap peristiwa pemeriksaan apa pun yang terjadi myformdan memberi tahu kotak centang mana yang diubah (dan tahu apakah itu diaktifkan atau dinonaktifkan)?

aeq
sumber

Jawaban:

247
$('#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
sumber
30
thissudah disetel ke elemen DOM kotak centang jadi this.checkedsudah cukup. Anda tidak perlu membuat objek jQuery lain untuk itu kecuali jika Anda berencana untuk memanipulasinya.
Walf
18
Hanya tip kecil. Anda akan mendapatkan peningkatan kinerja dengan menggunakan kotak centang input: di selektor Anda, bukan hanya: kotak centang karena yang terakhir diterjemahkan ke pemilih universal *: kotak centang.
jimmystormig
23
Klik tidak berada di dekat acara pemeriksaan mana pun .
Peter
27
Ini bukanlah jawaban terbaik. Jika Anda memiliki label yang sesuai untuk masukan Anda (seperti <label for='myInput'>Checkbox:</label><input id='myInput' name='myInput' type='checkbox'/>) dan Anda mengklik label tersebut, kotak centang akan dicentang, tetapi fungsi ini TIDAK akan dipanggil. Anda harus menggunakan .change()acara
Patrick
7
Jawaban ini tidak sepenuhnya memberikan jawaban - silakan lihat jawaban Anurag di bawah ini, yang merupakan jawaban JAUH lebih lengkap (dan akurat). Jawaban ini tentu saja sebagian benar, tetapi seperti yang dinyatakan, ini bukan jawaban terbaik.
Carnix
131

Gunakan acara perubahan.

$('#myform :checkbox').change(function() {
    // this represents the checkbox that was checked
    // do something with it
});
Anurag
sumber
5
Jika kotak centang disembunyikan, maka pengguna tidak akan dapat berinteraksi dengannya. Beri tahu saya jika Anda bermaksud lain.
Anurag
1
Ini tidak berlaku untuk $("input[name=check1]").prop('checked', true). Lihat jsfiddle.net/Z3E8V/2
Peter
15
Itu sesuai desain. Mengubah properti elemen DOM secara terprogram tidak memicu penangan kejadian terkait. Anda harus memecatnya secara manual.
Anurag
6
Ini harus menjadi jawaban yang dipilih, itu mencakup mengklik label kotak centang
Patrick
3
Dari dokumentasi jQuery: "Karena :checkboxmerupakan ekstensi jQuery dan bukan bagian dari spesifikasi CSS, kueri yang digunakan :checkboxtidak dapat memanfaatkan peningkatan kinerja yang disediakan oleh querySelectorAll()metode DOM asli . Untuk kinerja yang lebih baik di browser modern, gunakan [type="checkbox"]sebagai gantinya."
NXT
55

Ada beberapa jawaban yang berguna, tetapi tampaknya tidak ada yang mencakup semua opsi terbaru . Untuk itu, semua contoh saya juga memenuhi keberadaan labelelemen yang cocok dan juga memungkinkan Anda menambahkan kotak centang secara dinamis dan melihat hasilnya di panel samping (dengan mengarahkan ulang console.log).

  • Mendengarkan clickacara di checkboxesadalah tidak ide yang baik karena yang tidak akan memungkinkan untuk keyboard Toggling atau perubahan yang dibuat di mana pencocokan labelelemen diklik. Dengarkan selalu changeacaranya.

  • Gunakan :checkboxpseudo-selector jQuery , bukan input[type=checkbox]. :checkboxlebih pendek dan lebih mudah dibaca.

  • Gunakan is()dengan :checkedselektor-semu jQuery untuk menguji apakah kotak centang dicentang. Ini dijamin bekerja di semua browser.

Penangan kejadian dasar yang dilampirkan ke elemen yang ada:

$('#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/

Catatan:

  • Menggunakan :checkboxselektor, yang lebih disukai daripada menggunakaninput[type=checkbox]
  • Ini hanya menghubungkan ke elemen yang cocok yang ada pada saat acara itu terdaftar.

Penangan peristiwa yang didelegasikan yang dilampirkan ke elemen leluhur:

Penangan peristiwa yang didelegasikan dirancang untuk situasi di mana elemen mungkin belum ada (dimuat atau dibuat secara dinamis) dan sangat berguna. Mereka mendelegasikan tanggung jawab kepada elemen leluhur (karena itu istilahnya).

$('#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/

Catatan:

  • Ini bekerja dengan mendengarkan kejadian (dalam kasus ini change) untuk melambung ke elemen leluhur yang tidak berubah (dalam kasus ini #myform).
  • Ini kemudian menerapkan pemilih jQuery ( ':checkbox'dalam hal ini) hanya ke elemen dalam rantai gelembung .
  • Ini kemudian menerapkan fungsi penanganan kejadian hanya untuk elemen yang cocok yang menyebabkan kejadian.
  • Gunakan documentsebagai default untuk menghubungkan event handler yang didelegasikan, jika tidak ada yang lebih dekat / nyaman.
  • Jangan gunakan bodyuntuk melampirkan acara yang didelegasikan karena memiliki bug (berkaitan dengan gaya) yang dapat menghentikannya mendapatkan peristiwa mouse.

Hasil dari penangan yang didelegasikan adalah bahwa elemen yang cocok hanya perlu ada pada waktu peristiwa dan bukan saat penangan peristiwa didaftarkan. Ini memungkinkan konten yang ditambahkan secara dinamis untuk menghasilkan acara.

T: Apakah lebih lambat?

J: Selama peristiwa berada pada kecepatan interaksi pengguna, Anda tidak perlu khawatir tentang perbedaan kecepatan yang dapat diabaikan antara pengendali peristiwa yang didelegasikan dan pengendali yang terhubung langsung. Manfaat pendelegasian jauh lebih besar daripada kerugian kecil apa pun. Penangan peristiwa yang didelegasikan sebenarnya lebih cepat didaftarkan karena biasanya terhubung ke satu elemen yang cocok.


Mengapa tidak prop('checked', true)menghentikan changeacara tersebut?

Ini sebenarnya dengan desain. Jika itu benar-benar memecat acara, Anda akan dengan mudah masuk ke situasi pembaruan tanpa akhir. Sebagai gantinya, setelah mengubah properti yang dicentang, kirim peristiwa perubahan ke elemen yang sama menggunakan trigger(bukan triggerHandler):

misalnya tanpa triggerada peristiwa yang terjadi

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

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

misalnya dengan triggerperistiwa perubahan normal tertangkap

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

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

Catatan:

  • Jangan gunakan triggerHandlerseperti yang disarankan oleh satu pengguna, karena ini tidak akan menggembungkan peristiwa ke penangan peristiwa yang didelegasikan .

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

meskipun itu akan bekerja untuk penangan kejadian yang terhubung langsung ke elemen:

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

Peristiwa yang dipicu dengan .triggerHandler () tidak memunculkan hierarki DOM; jika mereka tidak ditangani oleh elemen target secara langsung, mereka tidak melakukan apa-apa.

Referensi: http://api.jquery.com/triggerhandler/

Jika ada yang memiliki fitur tambahan yang mereka rasa tidak tercakup oleh ini, mohon saran penambahan .

Hilang Coding
sumber
33

Menggunakan metode 'on' baru di jQuery (1.7): http://api.jquery.com/on/

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

    });
  • event handler akan terus hidup
  • akan menangkap jika kotak centang diubah oleh keyboard, tidak hanya klik
Allen Hamilton
sumber
1
Ini tidak berlaku untuk $("input[name=check1]").prop('checked', true). Lihat jsfiddle.net/Z3E8V/2
Peter
7
Tambahkan saja .triggerHandler('change');setelah .proppanggilan. Kemudian itu akan mengaktifkan kotak DAN memanggil acara tersebut.
Hanna
alternatif: $ (document) .on ('change', 'input [type = "checkbox"]', function () {$ ('input [type = "checkbox"]'). bukan (this) .prop ( 'diperiksa', salah);});
Yoosaf Abdulla
5
$('#myform input:checkbox').click(
 function(e){
   alert($(this).is(':checked'))
 }
)
Pemikir
sumber
val()tidak memberi tahu Anda jika checkedada true.
Walf
5

Mengakui fakta bahwa penanya secara khusus meminta jQuery dan bahwa jawaban yang dipilih benar, perlu dicatat bahwa masalah ini sebenarnya tidak memerlukan jQuery per kata. Jika seseorang ingin menyelesaikan masalah ini tanpanya, ia dapat dengan mudah mengatur onClickatribut dari kotak centang yang dia ingin tambahkan fungsionalitas tambahannya, seperti:

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

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

Chase Sandmann
sumber
5
Menempatkan event handler secara langsung di HTML bekerja, tentu saja. Tapi itu bertentangan langsung dengan KERING dan metodologi peningkatan progresif. Jawaban yang lebih akurat adalah "Anda tidak perlu jQuery untuk menambahkan penangan peristiwa" dan sebaliknya, menggunakan JS standar untuk melampirkan penangan klik dalam file JS terpisah daripada meletakkan atribut onclick di HTML. Melakukannya "berhasil" tetapi praktik pengkodean yang baik mengharuskan Anda menghindarinya jika memungkinkan (yang hampir selalu terjadi pada saat ini kecuali Anda harus mendukung IE6 atau semacamnya, yang bahkan menurut MS Anda tidak boleh melakukannya lagi)
Carnix
3

Saya telah mencoba kode dari jawaban pertama, itu tidak berfungsi tetapi saya telah bermain-main dan ini berfungsi untuk saya

$('#vip').change(function(){
    if ($(this).is(':checked')) {
        alert('checked');
    } else {
        alert('uncheck');
    }
});
Somwang Souksavatd
sumber