.keyCode vs. .which


228

Saya pikir ini akan dijawab di suatu tempat di Stack Overflow, tetapi saya tidak dapat menemukannya.

Jika saya mendengarkan acara penekanan tombol, haruskah saya menggunakan .keyCodeatau .whichuntuk menentukan apakah tombol Enter ditekan?

Saya selalu melakukan sesuatu seperti berikut:

$("#someid").keypress(function(e) {
  if (e.keyCode === 13) {
    e.preventDefault();
    // do something
  }
});

Tapi saya melihat contoh yang menggunakan .whichbukan .keyCode. Apa bedanya? Apakah satu browser lebih ramah silang dari yang lain?


Jawaban:


209

Catatan: Jawaban di bawah ini ditulis pada tahun 2010. Di sini bertahun-tahun kemudian, keduanya keyCodedan whichsudah usang dalam mendukung key(untuk kunci logis) dan code(untuk penempatan fisik kunci). Tetapi perhatikan bahwa IE tidak mendukung code, dan dukungannya keydidasarkan pada versi spesifikasi yang lebih lama sehingga tidak cukup benar. Saat saya menulis ini, Edge saat ini berdasarkan pada EdgeHTML dan Chakra tidak mendukung codebaik, tetapi Microsoft meluncurkan pengganti untuk Blink - dan V8 berbasis untuk Edge, yang mungkin melakukan / akan.


Beberapa browser digunakan keyCode, yang lain digunakanwhich .

Jika Anda menggunakan jQuery, Anda dapat menggunakan whichjQuery sebagai standar ; Lebih lanjut di sini.

Jika Anda tidak menggunakan jQuery, Anda dapat melakukan ini:

var key = 'which' in e ? e.which : e.keyCode;

Atau sebagai alternatif:

var key = e.which || e.keyCode || 0;

... yang menangani kemungkinan yang e.whichmungkin terjadi 0(dengan mengembalikannya 0pada akhirnya, menggunakan operator JavaScript yang sangat kuat|| ).


2
Terima kasih TJ Di mana saya akan menemukan referensi untuk ini? Bukannya aku tidak percaya padamu, aku hanya ingin tahu! ... Saya melihat Anda baru saja menambahkan itu, terima kasih. Jadi, bahkan bagi mereka yang tidak menggunakan jquery,. Yang merupakan pilihan yang lebih baik?
ScottE

7
@ScottE: Jika tidak menggunakan jQuery, Anda harus menangani ini sendiri secara eksplisit. Saya biasanya melakukannya seperti ini. var key = event.which || event.keyCode;Itu akan digunakan event.whichjika itu didefinisikan dan bukan falsey, atau event.keyCodejika whichtidak didefinisikan atau falsey. Secara teknis saya mungkin harus melakukan var key = typeof event.which === "undefined" ? event.keyCode : event.which;tetapi jika event.whichitu 0(mungkinkah demikian 0?), Saya tidak akan peduli dengan hal-hal yang saya lakukan.
TJ Crowder

2
@ScottE, berikut ini adalah referensi dasar: quirksmode.org/js/keys.html (tidak termasuk which, yang saya pikir hanya disediakan oleh jQuery tapi saya tidak 100% yakin, tetapi seharusnya Anda mulai melihat perbedaan browser)
Mottie

1
@fudgey: whichdisediakan untuk keypresssemua browser kecuali IE. Dan quirksmode tidak resmi di sini. Sebagai referensi, tautan yang diposting @TJ Crowder jauh lebih baik: unixpapa.com/js/key.html .
Tim Down

5
@TJ Crowder: Ya, whichproperti acara bisa nol, dan ini bisa membuat perbedaan besar untuk sebagian besar aplikasi. Misalnya, kunci yang tidak dapat dicetak di Firefox memiliki whichproperti nol dan keyCodeproperti yang sama dengan keydown. Tombol Beranda memiliki angka keyCode36 pada PC saya di Firefox, yang merupakan kode karakter untuk "$", yang akan membuatnya tidak mungkin untuk membedakan antara pengguna yang menekan tombol Rumah dan pengguna yang mengetik $ karakter menggunakan event.which || event.keyCode.
Tim Down

32

jQuery menjadi normal event.whichtergantung pada apakah event.which, event.keyCodeatau event.charCodedidukung oleh browser:

// Add which for key events
if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
   event.which = event.charCode != null ? event.charCode : event.keyCode;
}

Manfaat tambahan .whichadalah bahwa jQuery juga melakukannya untuk klik mouse:

// Add which for click: 1 === left; 2 === middle; 3 === right
// Note: button is not normalized, so don't use it
if ( !event.which && event.button !== undefined ) {
    event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
}

2
var key = event.which || event.charCode || event.keyCode
Anne van Rossum

@ anne-van-rossum, event.wich == null && ...uji hanya nol atau tidak ditentukan. event.wich || ...tes Anda untuk falsy (undefined, null, false, 0, '', dll)
aMarCruz

@ aMarCruz Falsy sengaja. Misalnya bugs.webkit.org/show_bug.cgi?id=16735 dengan pelaporan Webkit 0. Dan saya tidak berpikir memeriksa ""atau []menyakiti.
Anne van Rossum

20

Jika Anda tetap menggunakan vanilla Javascript, harap dicatat keyCode sekarang sudah tidak digunakan lagi dan akan dihapus:

Fitur ini telah dihapus dari standar Web. Meskipun beberapa browser mungkin masih mendukungnya, browser ini sedang dalam proses dijatuhkan. Hindari menggunakannya dan perbarui kode yang ada jika memungkinkan; lihat tabel kompatibilitas di bagian bawah halaman ini untuk memandu keputusan Anda. Ketahuilah bahwa fitur ini dapat berhenti bekerja kapan saja

https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode

Alih-alih gunakan: .key atau .code tergantung pada perilaku apa yang Anda inginkan: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code https://developer.mozilla.org/en -US / docs / Web / API / KeyboardEvent / key

Keduanya diimplementasikan pada browser modern.


.code sesuai dengan lokasi fisik tombol pada keyboard sedangkan .key sesuai dengan karakter yang dihasilkan oleh tombol yang ditekan terlepas dari lokasi.
Christopher

1
Baik 'kode' dan 'kunci' memiliki kebiasaan di browser modern. Menggunakan contoh "Cobalah" di MDN developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code di browser yang berbeda menunjukkan bahwa IE11 / IE Edge tidak menerapkan 'kode' dan 'kunci' implementasi tidak cocok dengan implementasi di Chrome / FF / Safari (perbedaan tampaknya terutama pada karakter kontrol seperti Escape dan Enter). Saya pikir menggunakan perpustakaan mungkin paling mudah kecuali jika Anda sendiri yang bertanggung jawab atas masalah ini. Saya benar-benar ingin ini menjadi jawabannya, tetapi IE mengacaukan yang satu ini :-(
Akrikos

Hmm ... sebenarnya tidak terlalu buruk untuk mengimplementasikan kunci dengan cara lintas browser. Kunci alfanumerik reguler hanya mengembalikan nilainya dan untuk tombol kontrol (escape, enter, tab, dll) muncul diterapkan secara identik di sebagian besar browser kecuali IE11 / Edge yang menerapkan versi spesifikasi yang lebih lama, jadi setidaknya hanya ada dua nilai yang mungkin untuk masing-masing kunci.
Akrikos

Saya akan menyarankan menggunakan keybukan code. Misalnya, jika Anda memiliki keyboard dengan tombol kontrol media, menekan tombol Putar / Jeda output "MediaPlayPause" untuk keydan "" untuk code.
thdoan

6

lihat ini: https://developer.mozilla.org/en-US/docs/Web/API/event.keyCode

Dalam peristiwa penekanan tombol, nilai Unicode dari tombol yang ditekan disimpan dalam properti keyCode atau charCode, tidak pernah keduanya. Jika tombol yang ditekan menghasilkan karakter (mis. 'A'), charCode diatur ke kode karakter tersebut, dengan menghormati huruf huruf. (Yaitu charCode memperhitungkan apakah tombol shift ditekan). Kalau tidak, kode tombol yang ditekan disimpan di keyCode. keyCode selalu diatur dalam peristiwa keydown dan keyup. Dalam kasus ini, charCode tidak pernah disetel. Untuk mendapatkan kode kunci terlepas dari apakah itu disimpan dalam keyCode atau charCode, kueri properti yang mana. Karakter yang dimasukkan melalui IME tidak mendaftar melalui keyCode atau charCode.


6

Saya akan merekomendasikan event.keysaat ini. Dokumen MDN: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key

event.KeyCodedan event.whichkeduanya memiliki peringatan usang yang tidak menyenangkan di bagian atas halaman MDN mereka:
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode https://developer.mozilla.org/en-US / docs / Web / API / KeyboardEvent / yang

Untuk tombol alfanumerik, event.keytampaknya diterapkan secara identik di semua browser. Untuk tombol kontrol (tab, enter, escape, dll),event.key memiliki nilai yang sama di Chrome / FF / Safari / Opera tetapi nilai yang berbeda di IE10 / 11 / Edge (IEs tampaknya menggunakan versi spesifikasi yang lebih lama tetapi cocok satu sama lain sebagai 14 Januari 2018).

Untuk kunci alfanumerik cek akan terlihat seperti:

event.key === 'a'

Untuk karakter kontrol, Anda perlu melakukan sesuatu seperti:

event.key === 'Esc' || event.key === 'Escape'

Saya menggunakan contoh di sini untuk menguji pada beberapa browser (saya harus membuka di codepen dan mengedit agar berfungsi dengan IE10): https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/ kode

event.code disebutkan dalam jawaban yang berbeda sebagai suatu kemungkinan, tetapi IE10 / 11 / Edge tidak mengimplementasikannya, jadi keluar jika Anda menginginkan dukungan IE.


2

Pustaka Javascript yang kuat untuk mengambil input keyboard dan kombinasi tombol dimasukkan. Tidak memiliki dependensi.

http://jaywcjlove.github.io/hotkeys/

hotkeys('ctrl+a,ctrl+b,r,f', function(event,handler){
    switch(handler.key){
        case "ctrl+a":alert('you pressed ctrl+a!');break;
        case "ctrl+b":alert('you pressed ctrl+b!');break;
        case "r":alert('you pressed r!');break;
        case "f":alert('you pressed f!');break;
    }
});

hotkeys memahami pengubah berikut: , shift, option, , alt, ctrl, control, command, dan .

Tombol khusus berikut dapat digunakan untuk cara pintas: backspace, tab, clear, enter, return, esc, escape, space, up, down, left, right, home, end, pageup, pagedown, del, deletedan f1melalui f19.


Itu shim Array.prototype.indexOf, jadi jika Anda menggunakan ini di perpustakaan lain, mungkin tidak cocok karena memodifikasi lingkup global. Tampaknya juga menggunakan usang event.keyCode.
Akrikos

Perpustakaan ini tidak mendeteksi Fn di laptop Vaio saya.
thdoan

0

Di Firefox, properti keyCode tidak berfungsi pada acara onkeypress (hanya akan mengembalikan 0). Untuk solusi lintas-browser, gunakan properti yang mana bersama dengan keyCode, misalnya:

var x = event.which || event.keyCode;  // Use either which or keyCode, depending on browser support
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.