Saya mencoba mengembangkan mesin game JavaScript dan saya menemukan masalah ini:
- Ketika saya menekan SPACEkarakter melompat.
- Ketika saya menekan →karakter bergerak ke kanan.
Masalahnya adalah ketika saya menekan kanan dan kemudian menekan spasi, karakter melompat dan kemudian berhenti bergerak.
Saya menggunakan keydown
fungsi ini untuk menekan tombol. Bagaimana saya dapat memeriksa apakah ada beberapa tombol yang ditekan sekaligus?
javascript
keydown
XCS
sumber
sumber
Jawaban:
Catatan: keyCode sekarang sudah tidak digunakan lagi.
Deteksi beberapa keystroke mudah jika Anda memahami konsepnya
Cara saya melakukannya adalah seperti ini:
Kode ini sangat sederhana: Karena komputer hanya melewati satu penekanan tombol pada satu waktu, sebuah array dibuat untuk melacak beberapa kunci. Array kemudian dapat digunakan untuk memeriksa satu atau lebih kunci sekaligus.
Hanya untuk menjelaskan, katakanlah Anda menekan Adan B, masing-masing menembakkan
keydown
peristiwa yang menetapkanmap[e.keyCode]
nilaie.type == keydown
, yang mengevaluasi benar atau salah . Sekarang keduanyamap[65]
danmap[66]
diatur ketrue
. Ketika Anda melepaskanA
,keyup
acara menyala, menyebabkan logika yang sama untuk menentukan hasil yang berlawanan untukmap[65]
(A), yang sekarang salah , tetapi karenamap[66]
(B) masih "turun" (itu belum memicu peristiwa keyup), itu tetap benar .The
map
array, melalui acara, terlihat seperti ini:Ada dua hal yang dapat Anda lakukan sekarang:
A) Pencatat Kunci ( contoh ) dapat dibuat sebagai referensi untuk nanti ketika Anda ingin mencari satu atau lebih kode kunci dengan cepat. Dengan asumsi Anda telah mendefinisikan elemen html dan menunjuknya dengan variabel
element
.Catatan: Anda dapat dengan mudah mengambil elemen dengan
id
atributnya.Ini menciptakan elemen html yang dapat dengan mudah direferensikan dalam javascript dengan
element
Anda bahkan tidak perlu menggunakan
document.getElementById()
atau$()
mengambilnya. Tetapi demi kompatibilitas, penggunaan jQuery$()
lebih banyak direkomendasikan.Pastikan tag skrip muncul setelah badan HTML. Kiat pengoptimalan : Sebagian besar situs web dengan nama besar memasang tag skrip setelah tag badan untuk pengoptimalan. Ini karena tag skrip memblokir elemen lebih lanjut dari pemuatan hingga skripnya selesai diunduh. Menempatkannya di depan konten memungkinkan konten untuk memuat sebelumnya.
B (di mana minat Anda terletak) Anda dapat memeriksa satu atau lebih kunci pada saat
/*insert conditional here*/
itu, ambil contoh ini:Sunting : Itu bukan cuplikan yang paling mudah dibaca. Keterbacaan penting, sehingga Anda dapat mencoba sesuatu seperti ini untuk memudahkan mata:
Pemakaian:
Ini lebih baik?
(akhir suntingan)
Contoh ini memeriksa CtrlShiftA, CtrlShiftBdanCtrlShiftC
Ini sesederhana itu :)
Catatan
Melacak Kode Kunci
Sebagai aturan umum, adalah praktik yang baik untuk mendokumentasikan kode, terutama hal-hal seperti Kode kunci (seperti
// CTRL+ENTER
) sehingga Anda dapat mengingat apa itu.Anda juga harus meletakkan kode kunci dalam urutan yang sama dengan dokumentasi (
CTRL+ENTER => map[17] && map[13]
, BUKANmap[13] && map[17]
). Dengan cara ini Anda tidak akan pernah bingung ketika Anda perlu kembali dan mengedit kode.Gotcha dengan rantai if-else
Jika memeriksa kombo dengan jumlah berbeda (seperti CtrlShiftAltEnterdan CtrlEnter), masukkan kombo yang lebih kecil setelah kombo yang lebih besar, atau kombo yang lebih kecil akan mengesampingkan kombo yang lebih besar jika mereka cukup mirip. Contoh:
Gotcha: "Kombo kunci ini tetap aktif meskipun saya tidak menekan tombol"
Saat berurusan dengan peringatan atau apa pun yang mengambil fokus dari jendela utama, Anda mungkin ingin menyertakan
map = []
untuk mengatur ulang array setelah kondisi selesai. Ini karena beberapa hal, sepertialert()
, mengalihkan fokus dari jendela utama dan menyebabkan acara 'keyup' tidak terpicu. Sebagai contoh:Gotcha: Default Peramban
Inilah hal yang menjengkelkan yang saya temukan, termasuk solusinya:
Masalah: Karena browser biasanya memiliki tindakan default pada kombo kunci (seperti CtrlDmengaktifkan jendela bookmark, atau CtrlShiftCmengaktifkan skynote di maxthon), Anda mungkin juga ingin menambahkan
return false
setelahmap = []
, sehingga pengguna situs Anda tidak akan frustrasi ketika "Duplicate File" fungsi, sedang memakai CtrlD, bookmark halaman sebagai gantinya.Tanpa
return false
, jendela Bookmark akan muncul, yang membuat pengguna kecewa.Pernyataan pengembalian (baru)
Oke, jadi Anda tidak selalu ingin keluar dari fungsi pada saat itu. Itu sebabnya
event.preventDefault()
fungsinya ada di sana. Apa yang dilakukannya adalah menetapkan bendera internal yang memberi tahu juru bahasa untuk tidak mengizinkan browser untuk menjalankan tindakan standarnya. Setelah itu, eksekusi fungsi berlanjut (padahalreturn
akan segera keluar fungsi).Pahami perbedaan ini sebelum Anda memutuskan apakah akan menggunakan
return false
ataue.preventDefault()
event.keyCode
sudah ditinggalkanPengguna SeanVieira menunjukkan dalam komentar yang
event.keyCode
sudah usang.Di sana, ia memberikan alternatif yang sangat baik:,
event.key
yang mengembalikan representasi string dari tombol yang ditekan, seperti"a"
untuk A, atau"Shift"
untukShift .Saya pergi ke depan dan memasak alat untuk memeriksa string tersebut.
element.onevent
vs.element.addEventListener
Penangan yang terdaftar
addEventListener
dapat ditumpuk, dan dipanggil dalam urutan pendaftaran, sementara pengaturan.onevent
langsung agak agresif dan menimpa apa pun yang sebelumnya Anda miliki.The
.onevent
properti tampaknya menimpa segala sesuatu dan perilakuev.preventDefault()
danreturn false;
bisa agak tak terduga.Dalam kedua kasus, penangan terdaftar melalui
addEventlistener
tampaknya lebih mudah untuk menulis dan mempertimbangkannya.Ada juga
attachEvent("onevent", callback)
dari implementasi non-standar Internet Explorer, tetapi ini sudah usang dan bahkan tidak berkaitan dengan JavaScript (itu berkaitan dengan bahasa esoterik yang disebut JScript ). Akan menjadi kepentingan terbaik Anda untuk menghindari kode polyglot sebanyak mungkin.Kelas pembantu
Untuk mengatasi kebingungan / keluhan, saya telah menulis "kelas" yang melakukan abstraksi ini ( tautan pastebin ):
Kelas ini tidak melakukan segalanya dan tidak akan menangani setiap kasus penggunaan yang mungkin. Saya bukan orang perpustakaan. Tetapi untuk penggunaan interaktif umum itu harus baik-baik saja.
Untuk menggunakan kelas ini, buat instance dan arahkan ke elemen yang ingin Anda kaitkan dengan input keyboard:
Apa yang akan dilakukan adalah melampirkan pendengar input baru ke elemen dengan
#txt
(mari kita asumsikan itu adalah textarea), dan menetapkan titik pantauan untuk kombo kunciCtrl+5
. Saat keduanyaCtrl
dan5
sedang turun, fungsi panggilan balik yang Anda berikan (dalam hal ini, fungsi yang menambah"FIVE "
textarea) akan dipanggil. Callback dikaitkan dengan namaprint_5
, jadi untuk menghapusnya, Anda cukup menggunakan:Untuk melepaskan
input_txt
daritxt
elemen:Dengan cara ini, pengumpulan sampah dapat mengambil objek (
input_txt
), harus dibuang, dan Anda tidak akan memiliki pendengar acara zombie yang tersisa.Untuk ketelitian, berikut adalah referensi cepat ke API kelas, disajikan dalam gaya C / Java sehingga Anda tahu apa yang mereka kembalikan dan argumen apa yang mereka harapkan.
Pembaruan 2017-12-02 Menanggapi permintaan untuk menerbitkan ini ke github, saya telah membuat inti .
Pembaruan 2018-07-21 Saya sudah bermain dengan pemrograman gaya deklaratif untuk sementara waktu, dan cara ini sekarang menjadi favorit pribadi saya: biola , pastebin
Secara umum, ini akan bekerja dengan case yang Anda inginkan secara realistis (ctrl, alt, shift), tetapi jika Anda perlu menekan, katakanlah,
a+w
pada saat yang sama, itu tidak akan terlalu sulit untuk "menggabungkan" pendekatan menjadi sebuah pencarian multi-kunci.Saya harap
jawaban yang dijelaskan diblog ini sangat membantu :)sumber
return false
vspreventDefault()
keyCode
sudah usang - jika Anda beralih kekey
maka Anda mendapatkan representasi karakter sebenarnya dari tombol yang bisa bagus.myString[5]
itu sama dengan5[myString]
, dan itu bahkan tidak akan memberi Anda peringatan kompilasi (bahkan dengan-Wall -pedantic
)? Itu karenapointer[offset]
notasi mengambil pointer, menambahkan offset, dan kemudian mereferensikan hasilnya, menjadikannyamyString[5]
sama dengan*(myString + 5)
.Anda harus menggunakan acara keydown untuk melacak tombol yang ditekan, dan Anda harus menggunakan acara keyup untuk melacak kapan tombol dilepaskan.
Lihat contoh ini: http://jsfiddle.net/vor0nwe/mkHsU/
(Pembaruan: Saya mereproduksi kode di sini, dalam kasus jsfiddle.net menebus :) HTML:
... dan Javascript (menggunakan jQuery):
Dalam contoh itu, saya menggunakan array untuk melacak tombol mana yang sedang ditekan. Dalam aplikasi nyata, Anda mungkin ingin
delete
setiap elemen begitu kunci terkait mereka telah dirilis.Perhatikan bahwa walaupun saya telah menggunakan jQuery untuk membuat hal-hal mudah bagi diri saya dalam contoh ini, konsep ini berfungsi dengan baik ketika bekerja di Javascript 'mentah'.
sumber
onblur
event handler, yang menghapus semua tombol yang ditekan dari array. Setelah kehilangan fokus, masuk akal jika harus menekan semua tombol lagi. Sayangnya, tidak ada JS yang setara denganGetKeyboardState
.sumber
Saya menggunakan cara ini (harus memeriksa dimanapun Shift + Ctrl ditekan):
sumber
untuk yang membutuhkan kode contoh lengkap. Kanan + Kiri ditambahkan
sumber
Buat keydown memanggil beberapa fungsi, dengan masing-masing fungsi memeriksa kunci tertentu dan merespons dengan tepat.
sumber
Saya akan mencoba menambahkan
keypress
Event
handlerkeydown
. Misalnya:Ini hanya dimaksudkan untuk menggambarkan suatu pola; Saya tidak akan masuk ke detail di sini (terutama tidak ke level2 +
Event
registrasi khusus browser ).Harap kirim kembali apakah ini membantu atau tidak.
sumber
Jika salah satu tombol yang ditekan adalah Alt / Crtl / Shift Anda dapat menggunakan metode ini:
sumber
sumber
Ini bukan metode universal, tetapi bermanfaat dalam beberapa kasus. Ini berguna untuk kombinasi seperti CTRL+ somethingatau Shift+ somethingatau CTRL+ Shift+ something, dll.
Contoh: Ketika Anda ingin mencetak halaman menggunakan CTRL+ P, penekanan tombol pertama selalu CTRLdiikuti oleh P. Sama dengan CTRL+ S, CTRL+ Udan kombinasi lainnya.
sumber
Bukan cara terbaik, saya tahu.
sumber
sumber