onKeyPress Vs. onKeyUp dan onKeyDown

329

Apa perbedaan antara ketiga acara ini? Setelah googling saya menemukan bahwa:

  • The onKeyDownevent dipicu ketika pengguna menekan tombol.
  • The onKeyUpevent dipicu ketika user melepaskan tombol.
  • The onKeyPressevent dipicu ketika pengguna menekan & rilis kunci ( onKeyDowndiikuti oleh onKeyUp).

Saya mengerti dua yang pertama, tetapi tidak onKeyPresssama dengan onKeyUp? Apakah mungkin untuk melepaskan kunci ( onKeyUp) tanpa menekannya ( onKeyDown)?

Ini agak membingungkan, dapatkah seseorang membersihkan ini untuk saya?

instantsetsuna
sumber
3
Saya menemukan bahwa jika saya menahan tombol TAB ke bawah, itu akan terus-menerus berputar melalui semua bidang dan hanya memicu 'onkeydown'.
nu everest
23
acara penekanan tombol mewakili karakter yang sedang diketik yang dapat digunakan untuk input, seperti 'a', 'D', '£', '©', dan sebagainya. Di sisi lain, peristiwa keydown dan keyup mewakili tombol APA SAJA yang diketik, yang mencakup hal-hal seperti backspace, tab, atas, bawah, rumah, akhir, dan sebagainya.
skcin7
2
"(atau apakah mungkin untuk melepaskan kunci (KeyUp) tanpa menekan (KeyDown) itu?)" - Ya. Misalnya, tombol tab: acara keyup mungkin tidak ditangkap oleh elemen yang sama dengan keydown.
Self Evident

Jawaban:

191

Periksa di sini untuk tautan yang diarsipkan yang awalnya digunakan dalam jawaban ini.

Dari tautan itu:

Secara teori, the onKeyDowndan onKeyUpevents mewakili kunci yang ditekan atau dilepaskan, sedangkan onKeyPressevent mewakili karakter yang sedang diketik. Implementasi teori tidak sama di semua browser.

dcp
sumber
18
Kumpulkan jsfiddle berdasarkan pada pos @ Falk untuk menunjukkan keanehan (menggunakan jquery): jsfiddle.net/zG9MF/2
fordareh
Saya tidak dapat melihat halaman yang ditautkan tetapi poin tentang 'karakter yang diketik' adalah yang penting jika Anda berencana menggunakan ini untuk segala jenis validasi. Acara penekanan tombol tidak menyala saat pengguna menghapus karakter, sehingga validasi Anda tidak akan diaktifkan.
Tony Merryfield
@ Tony Merryfield - tautan bekerja dengan baik untuk saya, saya baru memeriksanya lagi.
dcp
1
@dcp - Ya, cukup petunjuk untuk membuat saya di jalan yang benar. Saya baru saja menambahkan komentar saya untuk memperkuat poin bahwa acara tersebut hanya memicu ketika sebuah karakter diketik sebagai lawan dari penekanan tombol apa pun - Anda mendapatkan upvote saya;)
Tony Merryfield
1
Selain itu, pada penekanan tombol "panjang", peristiwa KeyDown terus menyala sampai kunci dilepaskan dalam hal ini, dimana KeyUp dipecat hanya sekali;)
Bernoulli IT
195

KeyPress, KeyUpDan KeyDownanalog dengan masing-masing: Click, MouseUp,dan MouseDown.

  1. Down terjadi dulu
  2. Press terjadi kedua (ketika teks dimasukkan)
  3. Up terjadi terakhir (ketika input teks selesai).

Pengecualiannya adalah webkit , yang memiliki acara ekstra di sana:

keydown
keypress
textInput     
keyup

Di bawah ini adalah cuplikan yang dapat Anda gunakan untuk melihat sendiri ketika acara dipecat:

window.addEventListener("keyup", log);
window.addEventListener("keypress", log);
window.addEventListener("keydown", log);

function log(event){
  console.log( event.type );
}

Robusto
sumber
1
Jadi, Apakah KeyPress hanya acara tambahan yang dilakukan KeyDown dan TextInput? Bagaimana itu (KeyPress) umumnya digunakan oleh pengembang?
instantsetsuna
78
+1 jawaban terbaik - The * Down terjadi pertama, * Tekan terjadi kedua (ketika teks dimasukkan), dan * Atas terjadi terakhir (ketika input teks selesai).
Scott Pelak
2
-1 karena sedikit eksperimen dalam cuplikan bertentangan dengan analogi Anda dengan peristiwa 'klik'. Acara 'klik' menyala pada saat yang sama dengan 'mouseup' (ketika Anda melepaskan tombol mouse), tetapi acara 'penekanan tombol' menyala pada saat yang sama dengan 'keydown' (ketika kunci pertama kali ditekan).
Mark Amery
2
@ Ragob Sebenarnya, keypressdan keydownperistiwa secara harfiah mendapatkan nilai yang sama .timeStamp, yang akurat untuk interval 5 mikrodetik, tapi itu sebenarnya bukan maksud saya. Maksud saya adalah bahwa clickacara tidak menyala sampai Anda melepaskan tombol mouse, jadi mengatakan itu keypressadalah versi keyboard clickmembuatnya seperti keypressjuga tidak akan menyala sampai Anda melepaskan kunci. Faktanya, bukan itu masalahnya: ia menyala ketika kuncinya ditekan, seperti keydownhalnya. Jadi keypresssebenarnya tidak analog clicksama sekali.
Mark Amery
2
@Robusto "bagaimana Anda menjelaskan 'penekanan tombol' selalu direkam setelah 'keydown'" - sederhana: tindakan pengguna yang sama (menekan tombol) segera memicu kedua penangan untuk didorong ke dalam antrian acara, tetapi dalam urutan tetap . "Anda hanya ingin memiliki argumen demi argumen" - Eh? Tesis inti jawaban Anda adalah bahwa keypress, keyup, dan keydownanalog dengan click, mouseup, dan mousedown. Bagi saya, interpretasi alami dari hal itu adalah bahwa keypressapi pada saat yang sama seperti keyup(seperti clickdan mouseup). Apa yang tidak Anda maksud, jika tidak itu?
Mark Amery
23

Sebagian besar jawaban di sini lebih berfokus pada teori daripada hal-hal praktis dan ada beberapa perbedaan besar antara keyupdan keypresskarena berkaitan dengan nilai-nilai bidang input, setidaknya di Firefox (diuji di 43).

Jika pengguna mengetik 1ke elemen input kosong:

  1. Nilai elemen input akan berupa string kosong (nilai lama) di dalam keypresshandler

  2. Nilai elemen input akan menjadi 1(nilai baru) di dalam keyuphandler.

Ini sangat penting jika Anda melakukan sesuatu yang bergantung pada mengetahui nilai baru setelah input daripada nilai saat ini seperti validasi inline atau tab otomatis.

Skenario:

  1. Pengguna mengetik 12345ke elemen input.
  2. Pengguna memilih teks 12345.
  3. Pengguna mengetik surat itu A.

Ketika keypressacara diaktifkan setelah memasukkan surat A, kotak teks sekarang hanya berisi surat A.

Tapi:

  1. Field.val () adalah 12345.
  2. $ Field.val (). Length adalah 5
  3. Pilihan pengguna adalah string kosong (mencegah Anda menentukan apa yang telah dihapus dengan menimpa pemilihan).

Jadi sepertinya peramban (Firefox 43) menghapus pilihan pengguna, lalu menyalakan keypressacara, lalu memperbarui konten bidang, lalu memecat keyup.

Nick
sumber
16

onkeydownditembakkan ketika kunci turun (seperti dalam pintasan; misalnya, dalam Ctrl+A, Ctrlditekan 'bawah'.

onkeyup dipecat ketika kunci dilepaskan (termasuk kunci pengubah / dll)

onkeypressdipecat sebagai kombinasi dari onkeydowndan onkeyup, atau tergantung pada pengulangan keyboard (saat onkeyuptidak diaktifkan). (Perilaku berulang ini adalah sesuatu yang belum saya uji. Jika Anda melakukan tes, tambahkan komentar!)

textInput(hanya webkit) dipecat ketika beberapa teks dimasukkan (misalnya, Shift+Aakan memasukkan huruf besar 'A', tetapi Ctrl+Aakan memilih teks dan tidak memasukkan input teks apa pun. Dalam hal ini, semua acara lainnya dipecat)

arunjitsingh
sumber
1
Hanya mengkonfirmasi bahwa, memang, "onkeypress" dipanggil berulang kali ketika tombol ditekan, dan "keyboard repeat" terjadi. Namun, ini juga berlaku untuk "onkeydown"! (yang tidak terduga, diberi nama)
Venryx
11

Pertama, mereka memiliki arti berbeda: mereka menembak:

  • KeyDown - ketika kunci ditekan ke bawah
  • KeyUp - ketika tombol ditekan dirilis , dan setelah nilai input / textarea diperbarui (satu-satunya di antaranya)
  • KeyPress - antara keduanya dan sebenarnya bukan berarti suatu tombol ditekan dan dilepaskan (lihat di bawah).

Kedua, beberapa kunci menembakkan beberapa peristiwa ini dan tidak memecat orang lain . Misalnya,

  • Abaikan tombol ditekan delete, panah, PgUp/ PgDn, home/ end, ctrl, alt, shiftdll sementara KeyDown dan KeyUp tidak (lihat rincian tentang escdi bawah);
  • ketika Anda beralih jendela melalui alt+ tabdi Windows, hanya KeyDown untuk altkebakaran karena pengalihan jendela terjadi sebelum peristiwa lain (dan KeyDown untuk tabdicegah oleh sistem, saya kira, setidaknya di Chrome 71).

Juga, Anda harus ingat bahwa event.keyCode(dan event.which) biasanya memiliki nilai yang sama untuk KeyDown dan KeyUp tetapi berbeda untuk KeyPress. Coba taman bermain yang saya buat. Ngomong-ngomong, saya perhatikan cukup aneh: di Chrome, ketika saya menekan ctrl+ adan input/ textareakosong, untuk KeyPress menyala dengan event.keyCode(dan event.which) sama dengan 1! (ketika input tidak kosong, itu tidak menyala sama sekali).

Akhirnya, ada beberapa pragmatik :

  • Untuk menangani panah, Anda mungkin perlu menggunakan onKeyDown: jika pengguna memegang , KeyDown akan diaktifkan beberapa kali (sementara KeyUp hanya akan menyala sekali ketika mereka melepaskan tombol). Juga, dalam beberapa kasus Anda dapat dengan mudah mencegah propagasi KeyDown tetapi tidak dapat (atau tidak bisa dengan mudah) mencegah propagasi KeyUp (misalnya, jika Anda ingin mengirim saat masuk tanpa menambahkan baris baru ke bidang teks).
  • Mengejutkan, ketika Anda memegang kunci, katakan textarea, baik KeyPress dan KeyDown menyala beberapa kali (Chrome 71), saya akan menggunakan KeyDown jika saya membutuhkan acara yang menyala beberapa kali dan KeyUp untuk pelepasan kunci tunggal.
  • KeyDown biasanya lebih baik untuk gim ketika Anda harus memberikan respons yang lebih baik terhadap tindakan mereka.
  • escbiasanya diproses melalui KeyDown: KeyPress tidak menyala dan KeyUp berperilaku berbeda untuk inputs dan textareas di browser yang berbeda (kebanyakan karena kehilangan fokus)
  • Jika Anda ingin menyesuaikan ketinggian area teks dengan konten, Anda mungkin tidak akan menggunakan onKeyDown melainkan onKeyPress ( PS ok, sebenarnya lebih baik menggunakan onChange untuk kasus ini ).

Saya telah menggunakan ketiganya dalam proyek saya tetapi sayangnya mungkin telah melupakan beberapa pragmatik. (untuk dicatat: ada juga inputdan changeacara)

YakovL
sumber
Saya belum memikirkan keyup menambahkan baris baru ke konten bidang, tapi itu sebenarnya penting.
FKEinternet
10

Ini artikel oleh Jan Wolter adalah bagian terbaik yang saya telah datang di, Anda dapat menemukan salinan arsip di sini jika link sudah mati.

Ini menjelaskan semua acara kunci browser dengan sangat baik,

Acara keydown terjadi ketika tombol ditekan, diikuti segera oleh acara penekanan tombol. Kemudian acara keyup dihasilkan ketika kunci dilepaskan.

Untuk memahami perbedaan antara keydown dan menekan tombol , hal ini berguna untuk membedakan antara karakter dan kunci . Sebuah kunci adalah tombol fisik pada keyboard komputer. Sebuah karakter adalah simbol diketik dengan menekan sebuah tombol. Pada keyboard AS, menekan 4tombol sambil menahan Shifttombol biasanya menghasilkan karakter "tanda dolar". Ini belum tentu terjadi pada setiap keyboard di dunia. Secara teori, peristiwa keydown dan keyup mewakili tombol yang ditekan atau dilepaskan, sedangkan penekanan tombolacara mewakili karakter yang diketik. Dalam praktiknya, ini tidak selalu seperti yang diterapkan.

Untuk sementara, beberapa browser meluncurkan acara tambahan, yang disebut textInput , segera setelah tombol ditekan . Versi awal standar DOM 3 dimaksudkan ini sebagai pengganti acara penekanan tombol , tetapi seluruh gagasan kemudian dicabut. Webkit mendukung ini antara versi 525 dan 533, dan saya diberitahu bahwa IE mendukungnya, tetapi saya tidak pernah mendeteksinya, mungkin karena Webkit mengharuskannya disebut textInput sedangkan IE menyebutnya textinput .

Ada juga peristiwa yang disebut input , didukung oleh semua browser, yang dipecat tepat setelah perubahan dilakukan ke textarea atau bidang input. Biasanya penekanan tombol akan menyala, maka karakter yang diketik akan muncul di area teks, kemudian input akan diaktifkan. Acara masukan tidak benar-benar memberikan informasi tentang kunci apa yang diketik - Anda harus memeriksa kotak teks untuk mencari tahu apa yang berubah - jadi kami tidak benar-benar menganggapnya sebagai peristiwa utama dan tidak benar-benar mendokumentasikannya di sini . Meskipun awalnya hanya didefinisikan untuk textareas dan kotak input, saya percaya ada beberapa gerakan menuju generalisasi untuk menembak pada objek jenis lain juga.

Suraj Jain
sumber
Jawaban terbaik, jadi bagaimana Anda bisa mendapatkan, misalnya, simbol tanda dolar dari penekanan tombol?
bluejayke
10

Tampaknya onkeypress dan onkeydown melakukan hal yang sama (isi perbedaan kecil tombol pintas yang telah disebutkan di atas).

Anda dapat mencoba ini:

<textarea type="text" onkeypress="this.value=this.value + 'onkeypress '"></textarea>
<textarea type="text" onkeydown="this.value=this.value + 'onkeydown '" ></textarea>
<textarea type="text" onkeyup="this.value=this.value + 'onkeyup '" ></textarea>

Dan Anda akan melihat bahwa peristiwa onkeypress dan onkeydown keduanya dipicu saat tombol ditekan dan tidak ketika tombol ditekan.

Perbedaannya adalah bahwa acara tersebut dipicu tidak hanya sekali tetapi berkali-kali (selama Anda menahan tombolnya). Waspadai hal itu dan tangani mereka dengan tepat.

Falk
sumber
Ctrl, Shift, CapsLock, Backspace dan kuncikeypress lain yang tidak mengetik sesuatu tidak menyebabkan suatu peristiwa, tetapi mereka selalu memicu a keydown.
CPHPython
8

Acara onkeypress bekerja untuk semua kunci kecuali ALT, CTRL, SHIFT, ESC di semua browser di mana acara onkeydown bekerja untuk semua kunci. Berarti acara onkeydown menangkap semua kunci.

Mohd Sadiq
sumber
keypress juga mengabaikan delete, panah, home / end, PgUp / PgDn, lihat jawaban saya untuk detailnya (Anda mungkin ingin memperbarui jawaban Anda juga)
YakovL
4

Hanya ingin berbagi rasa ingin tahu:

saat menggunakan acara onkeydown untuk mengaktifkan metode JS, charcode untuk acara itu TIDAK sama dengan yang Anda dapatkan dengan onkeypress!

Misalnya tombol numpad akan mengembalikan kode yang sama dengan tombol angka di atas tombol huruf saat menggunakan onkeypress, tetapi BUKAN saat menggunakan onkeydown!

Butuh beberapa detik untuk mencari tahu mengapa skrip saya yang memeriksa beberapa kode gagal saat menggunakan onkeydown!

Demo: https://www.w3schools.com/code/tryit.asp?filename=FMMBXKZLP1MK

dan ya. Saya tahu definisi metode berbeda .. tetapi hal yang sangat membingungkan adalah bahwa dalam kedua metode hasil acara diambil menggunakan event.keyCode .. tetapi mereka tidak mengembalikan nilai yang sama .. tidak terlalu implementasi deklaratif.

Drummer
sumber
Tampaknya semuanya sama untuk Karakter Numerik ( 0123456789)
Mrigank Pawagi
Dan apakah Anda memperhatikan bahwa keyDown memberikan KUNCI pada keyboard, sementara keyPress memberikan Karakter persis yang baru saja kami ketikkan (atau klik)
Mrigank Pawagi
2

Pada dasarnya, peristiwa ini bertindak berbeda pada jenis dan versi peramban yang berbeda, saya membuat tes jsBin kecil dan Anda dapat memeriksa konsol untuk mengetahui bagaimana perilaku peristiwa ini untuk lingkungan yang ditargetkan, harap bantuan ini. http://jsbin.com/zipivadu/10/edit

Ken Chan
sumber
1

Jawaban yang Diperbarui:

KeyDown

  • Kebakaran beberapa kali saat Anda menahan tombol.
  • Kunci meta kebakaran.

Tekan tombol

  • Kebakaran beberapa kali saat Anda menahan tombol.
  • Apakah tidak memecat meta kunci.

KeyUp

  • Kebakaran sekali di akhir ketika Anda melepaskan kunci.
  • Kunci meta kebakaran.

Ini adalah perilaku di keduanya addEventListenerdan jQuery.

https://jsbin.com/vebaholamu/1/edit?js,console,output <- coba contoh

menunjukkan contoh dengan menahan SSS

(jawaban telah diedit dengan respons, tangkapan layar & contoh yang benar)

Quang Van
sumber
Kecuali untuk keydown yang menyala beberapa kali juga
bluejayke
-1, karena setidaknya satu detail tentang ini salah di setidaknya Chrome; seperti yang dikatakan @bluejayke, KeyDown juga akan menyala berulang kali saat Anda menekan tombol
Mark Amery
Ya kalian benar, maaf atas kesalahan saya; jawaban diedit.
Quang Van
0

Beberapa fakta praktis yang mungkin berguna untuk memutuskan acara mana yang akan ditangani (jalankan skrip di bawah ini dan fokus pada kotak input):

$('input').on('keyup keydown keypress',e=>console.log(e.type, e.keyCode, e.which, e.key))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input/>

Mendesak:

  • kunci tidak memasukkan / mengetik (mis. Shift, Ctrl) tidak akan memicu a keypress. Tekan Ctrldan lepaskan:

    keydown 17 17 Kontrol

    keyup 17 17 Kontrol

  • kunci dari keyboard yang menerapkan transformasi karakter ke karakter lain dapat menyebabkan Mati dan menduplikasi "kunci" (mis. ~, ´) pada keydown. Tekan ´dan lepaskan untuk menampilkan ganda ´´:

    keydown 192 192 Mati

    keydown 192 192 ´´

    penekanan tombol 180 180 ´

    penekanan tombol 180 180 ´

    keyup 192 192 Mati

Selain itu, input yang tidak diketik (mis. Rentang <input type="range">) masih akan memicu semua kejadian keyup, keydown dan penekanan tombol sesuai dengan tombol yang ditekan.

CPHPython
sumber