Masukkan Password
47 Menangani Peristiwa Keyboard
Lecture ini membahas keyboard events, yaitu bagaimana JavaScript bisa mengetahui bahwa user menekan atau melepaskan tombol keyboard, lalu menjalankan suatu aksi berdasarkan tombol tersebut.
Contoh yang dibuat instructor sangat bagus:
Modal Calculate EMI bisa ditutup bukan hanya dengan klik tombol OK, tetapi juga dengan menekan tombol Enter.
Jadi lecture ini menghubungkan beberapa materi yang sudah kamu pelajari sebelumnya:
DOM
↓
Event
↓
addEventListener()
↓
Keyboard Event
↓
Event Object
↓
event.key / event.keyCode
↓
if condition
↓
Function
↓
classList
Mari kita bedah pelan-pelan.
1. Apa itu Keyboard Event?
Sebelumnya kamu sudah belajar event seperti:
button.addEventListener("click", function () {
...
});
Artinya:
“Kalau button diklik, jalankan function.”
Sekarang event-nya bukan click.
Event-nya berasal dari keyboard.
Misalnya user menekan:
Enter
Shift
Ctrl
A
B
1
Space
ArrowUp
Browser bisa memberi tahu JavaScript:
“Hei, user baru saja menekan tombol keyboard.”
Itulah keyboard event.
2. Tiga keyboard event yang diperkenalkan
Instructor menyebut tiga jenis:
keydown
keypress
keyup
Gambaran sederhananya:
User menekan tombol
↓
keydown
↓
tombol tetap ditekan
↓
keyup
↓
User melepaskan tombol
keypress adalah event lama yang dulu digunakan untuk karakter yang diketik, tetapi untuk kode modern sebaiknya jangan menjadikannya pilihan utama. Biasanya gunakan keydown atau keyup.
3. keydown
keydown terjadi ketika tombol keyboard ditekan ke bawah.
Misalnya:
Tekan ENTER
↓
keydown
JavaScript bisa menangkapnya:
document.addEventListener("keydown", function (event) {
console.log(event);
});
Sekarang setiap kali tombol keyboard ditekan, function tersebut dijalankan.
4. keyup
keyup terjadi ketika tombol yang sebelumnya ditekan dilepaskan.
Misalnya:
Tekan Space
↓
keydown
Lepaskan Space
↓
keyup
Jadi:
keydown = tombol ditekan
keyup = tombol dilepas
5. Contoh penggunaan keydown dan keyup
Bayangkan game.
Kamu ingin karakter terus menembak selama tombol Space ditekan.
Secara konsep:
SPACE ditekan
↓
keydown
↓
mulai menembak
↓
SPACE masih ditekan
↓
tetap menembak
↓
SPACE dilepas
↓
keyup
↓
berhenti menembak
Ini contoh kenapa kita kadang membutuhkan keydown dan keyup.
6. Bagaimana dengan keypress?
Lecture menjelaskan bahwa keypress digunakan untuk character keys seperti:
A
B
C
1
2
3
!
@
#
Sedangkan keydown bisa menangkap lebih banyak jenis tombol, termasuk:
Enter
Shift
Ctrl
ArrowUp
Escape
Namun ada catatan teknis penting:
keypresssekarang sudah deprecated/obsolete di web modern.
Jadi untuk JavaScript modern, mental model yang lebih baik adalah:
Butuh mengetahui tombol ditekan?
↓
keydown
atau:
Butuh mengetahui tombol dilepas?
↓
keyup
Tidak perlu terlalu fokus menggunakan keypress untuk project baru.
7. Kenapa listener dipasang di document?
Ini bagian yang sangat penting.
Sebelumnya kamu belajar:
button.addEventListener("click", ...)
karena kita ingin mendengarkan event pada button.
Kalau:
input.addEventListener("focus", ...)
kita mendengarkan event pada input.
Tapi keyboard event dalam contoh ini ingin ditangkap secara global.
Maksudnya:
Kita tidak peduli user sedang fokus pada element mana. Kita ingin tahu apakah user menekan keyboard.
Maka:
document.addEventListener(...)
8. Kenapa bukan button?
Misalnya kita melakukan:
button.addEventListener("keydown", function () {
...
});
Maka keyboard event tersebut berkaitan dengan element tersebut.
Tetapi tujuan lecture:
“Di seluruh halaman, kalau user menekan Enter, tutup modal.”
Maka lebih masuk akal:
document.addEventListener("keydown", function (event) {
...
});
Visualnya:
DOCUMENT
│
┌──────────┼──────────┐
↓ ↓ ↓
input button div
│ │ │
└──────────┼──────────┘
↑
keyboard event
document menjadi tempat kita memasang listener global.
9. Bentuk dasar addEventListener
Kode dasarnya:
document.addEventListener(
"keydown",
function (event) {
...
}
);
Ada tiga bagian penting:
document
↓
tempat listener dipasang
"keydown"
↓
event yang ingin didengarkan
function(event)
↓
handler/callback yang dijalankan
10. Event object
Ini adalah konsep yang sudah kamu pelajari sebelumnya.
Ketika event terjadi:
function (event) {
...
}
JavaScript memberikan sebuah event object.
Misalnya:
document.addEventListener("keydown", function (event) {
console.log(event);
});
Kalau kamu menekan Enter, event berisi informasi mengenai kejadian tersebut.
Kurang lebih:
event
├── key
├── code
├── keyCode
├── type
├── ...
Ada banyak informasi lain.
Tetapi lecture ini fokus pada:
event.key
dan:
event.keyCode
11. event.key
Ini yang paling mudah dipahami.
event.key
berarti:
“Tombol apa yang ditekan?”
Contoh:
| Tombol | event.key |
|---|---|
| A | "a" / "A" tergantung konteks |
| Enter | "Enter" |
| Shift | "Shift" |
| Escape | "Escape" |
| Space | " " |
| ArrowUp | "ArrowUp" |
Jadi kalau user menekan Enter:
console.log(event.key);
hasilnya:
Enter
12. event.keyCode
Lecture juga menggunakan:
event.keyCode
Untuk Enter, hasilnya:
13
Jadi:
event.keyCode === 13
dapat digunakan untuk mengenali Enter.
Tetapi ada catatan penting:
keyCodeadalah API lama/deprecated.
Untuk kode modern, lebih baik menggunakan:
event.key === "Enter"
Daripada:
event.keyCode === 13
Instructor menggunakan keyCode karena kemungkinan course tersebut dibuat menggunakan pendekatan JavaScript yang lebih lama.
13. Mana yang sebaiknya kamu gunakan?
Untuk project modern:
if (event.key === "Enter") {
...
}
lebih disarankan.
Daripada:
if (event.keyCode === 13) {
...
}
Kenapa?
Karena "Enter" jauh lebih mudah dibaca.
Bandingkan:
if (event.keyCode === 13)
Kita harus ingat:
13 itu apa?
Sedangkan:
if (event.key === "Enter")
langsung jelas:
Kalau tombolnya Enter.
14. Contoh sederhana
Misalnya:
document.addEventListener("keydown", function (event) {
console.log(event.key);
});
Jika user melakukan:
A
console:
a
Tekan:
Shift
console:
Shift
Tekan:
Enter
console:
Enter
Tekan:
Escape
console:
Escape
Jadi event.key memberi tahu nama tombol yang ditekan.
15. Sekarang kita masuk ke kebutuhan aplikasi
Ingat modal Calculate EMI.
Sebelumnya:
Calculate EMI
↓
Modal muncul
↓
Klik OK
↓
Modal ditutup
Instructor ingin menambahkan:
Calculate EMI
↓
Modal muncul
↓
User bisa:
├── klik OK
└── tekan Enter
↓
Modal ditutup
Jadi kita memiliki dua cara untuk menjalankan aksi yang sama.
16. Kenapa function hideModal() dibuat?
Sebelumnya mungkin kode untuk tombol OK langsung seperti:
closeModalButton.addEventListener("click", function () {
modalDiv.classList.add("hide");
});
Masalahnya sekarang kita membutuhkan logic yang sama dari dua tempat:
Klik OK
↓
hide modal
Tekan Enter
↓
hide modal
Kalau logic ditulis dua kali:
// click
modalDiv.classList.add("hide");
// keyboard
modalDiv.classList.add("hide");
sebenarnya bisa bekerja.
Tetapi tidak ideal.
Lebih baik buat function:
function hideModal() {
modalDiv.classList.add("hide");
}
Kemudian:
closeModalButton.addEventListener("click", hideModal);
dan:
document.addEventListener("keydown", function (event) {
if (...) {
hideModal();
}
});
17. Ini contoh code reuse
Ini sebenarnya kembali ke materi function.
Kita memiliki satu pekerjaan:
hide modal
Kemudian ada dua pemicu:
CLICK
↓
hideModal()
ENTER
↓
hideModal()
Jadi:
┌── click ──→ hideModal()
│
EVENT ─────────┤
│
└── Enter ──→ hideModal()
Function hideModal() menjadi reusable.
18. Kenapa modalDiv dipindahkan ke scope luar?
Instructor kemudian melakukan refactoring.
Sebelumnya mungkin:
function calculateEmi() {
let modalDiv = document.getElementById(...);
}
Kalau modalDiv dideklarasikan di dalam function:
function calculateEmi() {
let modalDiv = ...;
}
maka variable tersebut hanya tersedia di dalam function itu.
Tetapi sekarang kita juga membutuhkan modalDiv di:
hideModal()
dan:
keydown callback
Maka instructor memindahkannya ke scope yang lebih luar.
Misalnya:
const modalDiv =
document.getElementById("calculate-emi-modal");
Sekarang beberapa function bisa mengaksesnya.
Ini kembali ke materi scope yang sudah kamu pelajari.
19. Hubungan dengan scope
Sebelumnya:
GLOBAL
│
├── calculateEmi()
│ └── modalDiv
│
└── hideModal()
hideModal() tidak bisa melihat modalDiv yang hanya hidup di dalam calculateEmi().
Setelah dipindahkan:
GLOBAL
│
├── modalDiv
│
├── calculateEmi()
│
├── hideModal()
│
└── keyboard handler
Sekarang semuanya bisa mengakses modalDiv.
Jadi ini bukan sekadar masalah DOM.
Ini juga mengulang konsep:
scope menentukan variable mana yang bisa diakses dari mana.
20. classList.contains()
Nah, ini method baru yang diperkenalkan lecture.
Sebelumnya kamu sudah belajar:
element.classList.add("hide");
dan:
element.classList.remove("hide");
Sekarang:
element.classList.contains("hide");
Artinya:
“Apakah element ini mempunyai class
hide?”
Return value-nya adalah Boolean:
true
false
21. Contoh contains()
Misalnya HTML:
<div class="modal hide"></div>
Kemudian:
modalDiv.classList.contains("hide");
hasilnya:
true
Karena class hide memang ada.
Kalau:
<div class="modal"></div>
maka:
modalDiv.classList.contains("hide");
hasilnya:
false
22. Hubungkan dengan add() dan remove()
Sekarang kamu punya tiga method penting:
classList
│
├── add()
├── remove()
└── contains()
add()
element.classList.add("hide");
Tambahkan class.
remove()
element.classList.remove("hide");
Hapus class.
contains()
element.classList.contains("hide");
Cek apakah class ada.
23. Kenapa menggunakan contains()?
Instructor ingin:
Hanya jalankan
hideModal()kalau modal memang sedang tampil.
Misalnya:
if (!modalDiv.classList.contains("hide")) {
hideModal();
}
Mari baca dari kiri ke kanan.
Pertama:
modalDiv.classList.contains("hide")
artinya:
Apakah modal memiliki class
hide?
Misalnya hasilnya:
false
Artinya:
Modal tidak memiliki class hide.
Kemudian:
!false
menjadi:
true
Maka:
hideModal();
dijalankan.
24. Kenapa ada !?
Ini kembali ke logical operator yang sudah kamu pelajari.
!
berarti NOT.
Contoh:
!true // false
!false // true
Jadi:
!modalDiv.classList.contains("hide")
bisa dibaca:
“Modal tidak memiliki class
hide.”
25. Baca kondisi ini dengan bahasa manusia
Misalnya:
if (
event.key === "Enter" &&
!modalDiv.classList.contains("hide")
) {
hideModal();
}
Jangan langsung lihat sebagai kode rumit.
Terjemahkan:
Jika tombol yang ditekan adalah Enter DAN modal sedang tidak disembunyikan, maka sembunyikan modal.
Itu saja.
26. Kenapa kondisi modal perlu dicek?
Bayangkan user sedang berada di halaman biasa.
Modal tidak sedang terbuka.
User menekan:
Enter
Kalau listener kita hanya:
if (event.key === "Enter") {
hideModal();
}
maka hideModal() tetap dijalankan.
Padahal modal sedang tidak tampil.
Secara praktis mungkin tidak menyebabkan masalah besar karena add("hide") hanya memastikan class ada, tetapi secara logika kita sebenarnya ingin:
Enter hanya digunakan untuk menutup modal kalau modal memang sedang terbuka.
Maka:
!modalDiv.classList.contains("hide")
digunakan.
27. Kondisi lengkap
Secara konsep:
document.addEventListener("keydown", function (event) {
if (
event.key === "Enter" &&
!modalDiv.classList.contains("hide")
) {
hideModal();
}
});
Ada dua syarat:
Syarat 1
event.key === "Enter"
Harus Enter.
Syarat 2
!modalDiv.classList.contains("hide")
Modal harus sedang terlihat.
Karena menggunakan &&:
Enter? ──────────────── YES
│
↓
Modal sedang terlihat? ─ YES
│
↓
hideModal()
Kalau salah satu FALSE:
tidak melakukan apa-apa
28. Contoh situasi
Situasi A — Modal terbuka + Enter
event.key = "Enter"
modal memiliki "hide"?
NO
!false
↓
true
true && true
↓
true
hideModal()
Modal ditutup.
Situasi B — Modal terbuka + Shift
event.key = "Shift"
event.key === "Enter"
↓
false
false && ...
↓
false
Modal tidak ditutup.
Situasi C — Modal terbuka + D
event.key = "d"
"d" === "Enter"
↓
false
Tidak terjadi apa-apa.
Situasi D — Modal tertutup + Enter
event.key === "Enter"
↓
true
modal memiliki hide?
↓
true
!true
↓
false
true && false
↓
false
hideModal() tidak dijalankan.
29. console.log(event.key) untuk debugging
Instructor kemudian melakukan:
console.log(event.key);
Ini sangat bagus untuk belajar.
Misalnya user menekan:
Enter
console:
Enter
Tekan:
Shift
console:
Shift
Tekan:
d
console:
d
Jadi kita bisa melihat apa yang sebenarnya dikirim browser melalui event object.
30. Event listener berjalan setiap kali keyboard ditekan
Perhatikan ini:
document.addEventListener("keydown", function (event) {
console.log(event.key);
});
Function tersebut akan dipanggil berkali-kali.
Misalnya user mengetik:
HELLO
akan ada event untuk setiap tombol:
H
E
L
L
O
Secara sederhana:
keydown H → callback
keydown E → callback
keydown L → callback
keydown L → callback
keydown O → callback
Jadi event listener tidak berjalan satu kali saja.
Dia tetap “mendengarkan”.
31. Analogi event listener
Bayangkan ada satpam di pintu:
document
│
└── 👮 keyboard listener
Satpam terus mendengarkan.
User:
Shift
Satpam:
“Shift ditekan.”
User:
A
Satpam:
“A ditekan.”
User:
Enter
Satpam:
“Enter ditekan.”
Kemudian JavaScript memeriksa:
if (event.key === "Enter")
Kalau benar:
“Oke, jalankan
hideModal().”
32. Jangan salah memahami event
Perhatikan:
function (event) {
event ini bukan variable yang kamu buat sendiri dengan data random.
Browser memberikan object tersebut ketika event terjadi.
Mirip dengan lecture form sebelumnya:
function applyForLoan(event) {
event.preventDefault();
}
Di sana event berisi informasi mengenai event klik.
Sekarang:
document.addEventListener("keydown", function (event) {
...
});
event berisi informasi mengenai keyboard event.
33. Event object bisa berbeda tergantung event
Misalnya:
Click
button.addEventListener("click", function (event) {
...
});
event object berisi informasi tentang click.
Keyboard
document.addEventListener("keydown", function (event) {
...
});
event object berisi informasi tentang keyboard.
Mouse
element.addEventListener("mouseover", function (event) {
...
});
event object berisi informasi tentang mouse event.
Jadi:
EVENT
↓
EVENT OBJECT
↓
informasi tentang event tersebut
34. Hubungan key dan keyCode
Dalam lecture kamu melihat:
event.key
dan:
event.keyCode
Misalnya Enter:
event.key
↓
"Enter"
event.keyCode
↓
13
Namun untuk JavaScript modern, gunakan:
event.key === "Enter"
Lebih readable dan lebih modern.
35. key vs code — catatan teknis penting
Ada satu hal yang tidak dibahas lecture tetapi bagus kamu ketahui nanti.
Selain key, ada juga:
event.code
Perbedaannya secara sederhana:
event.key
→ karakter/nama tombol berdasarkan input
event.code
→ tombol fisik/key position pada keyboard
Contoh sederhana:
event.key = "a"
event.code = "KeyA"
Untuk Enter:
event.key = "Enter"
event.code = "Enter"
Untuk kebutuhan lecture ini, cukup gunakan:
event.key === "Enter"
36. Struktur final logic
Kalau ditulis menggunakan pendekatan modern:
const modalDiv =
document.getElementById("calculate-emi-modal");
function hideModal() {
modalDiv.classList.add("hide");
}
closeModalButton.addEventListener("click", hideModal);
document.addEventListener("keydown", function (event) {
if (
event.key === "Enter" &&
!modalDiv.classList.contains("hide")
) {
hideModal();
}
});
Perhatikan bahwa satu function:
hideModal
dipakai oleh dua event:
click
↓
hideModal()
keydown + Enter
↓
hideModal()
Ini jauh lebih baik daripada menulis logic yang sama berulang kali.
37. Connection dengan materi sebelumnya
Lecture ini sebenarnya mengulang banyak hal yang sudah kamu pelajari.
Event listener
Dari lecture sebelumnya:
element.addEventListener("click", handler);
Sekarang:
document.addEventListener("keydown", handler);
Event object
Sebelumnya:
event.preventDefault();
Sekarang:
event.key
Function
Sebelumnya:
function hideModal() {
...
}
Sekarang function tersebut digunakan oleh beberapa event.
Scope
modalDiv dipindahkan ke scope yang lebih luas agar bisa digunakan oleh beberapa bagian program.
Logical operator
&&
!
digunakan dalam kondisi.
DOM
modalDiv.classList.add("hide");
memanipulasi DOM.
classList
Sekarang kamu tahu tiga operasi:
add()
remove()
contains()
38. Flow keseluruhan lecture
Ini mungkin diagram yang paling penting untuk kamu simpan:
User menekan keyboard
↓
keydown
↓
document listener menangkap event
↓
callback function menerima event
↓
event.key
↓
Apakah key === "Enter"?
/ \
NO YES
↓ ↓
selesai cek modal
↓
modal sedang terlihat?
/ \
NO YES
↓ ↓
selesai hideModal()
↓
classList.add("hide")
↓
modal tersembunyi
39. Mental model classList
Sekarang bayangkan classList seperti daftar label yang menempel pada element.
Misalnya:
<div class="modal hide"></div>
Daftarnya:
classList
├── modal
└── hide
add
classList.add("active");
menjadi:
modal
hide
active
remove
classList.remove("hide");
menjadi:
modal
active
contains
classList.contains("hide");
bertanya:
“Apakah
hideada di daftar?”
Jawab:
true / false
40. Hal penting tentang “global keyboard event”
Ketika instructor mengatakan keyboard events adalah “global events”, pahami sebagai:
Kita dapat mendengarkan keyboard pada level
document, sehingga tidak perlu memasang listener satu per satu pada setiap element.
Contoh:
document.addEventListener("keydown", ...);
berbeda dengan:
button.addEventListener("keydown", ...);
Yang pertama cocok untuk kebutuhan global seperti:
Esc → tutup modal
Enter → submit/confirm
Arrow keys → navigasi
Ctrl + ... → shortcut
41. Contoh nyata lain: Escape untuk modal
Setelah memahami lecture ini, kamu bisa membuat:
document.addEventListener("keydown", function (event) {
if (event.key === "Escape") {
hideModal();
}
});
Sekarang:
Modal terbuka
↓
Tekan Escape
↓
event.key === "Escape"
↓
hideModal()
↓
Modal tertutup
Ini pola yang sangat umum dalam website modern.
42. Contoh shortcut keyboard
Misalnya:
document.addEventListener("keydown", function (event) {
if (event.key === "Enter") {
console.log("Enter pressed");
}
});
Atau:
document.addEventListener("keydown", function (event) {
if (event.key === "Escape") {
console.log("Escape pressed");
}
});
Atau:
document.addEventListener("keydown", function (event) {
if (event.key === "ArrowUp") {
console.log("Move up");
}
});
Sekarang kamu sudah mulai bisa membuat keyboard shortcuts.
43. Catatan penting: jangan terlalu terpaku pada keyCode
Karena lecture menggunakan:
event.keyCode === 13
jangan sampai kamu menganggap itu cara modern yang wajib digunakan.
Untuk code baru, lebih baik:
event.key === "Enter"
Jadi kalau kamu melihat tutorial lama:
if (event.keyCode === 13)
kamu sekarang tahu:
“Oh, itu cara lama untuk mendeteksi Enter.”
Sedangkan kamu sebaiknya menulis:
if (event.key === "Enter")
44. Cheat sheet keyboard events
| Konsep | Fungsi |
|---|---|
keydown | tombol ditekan |
keyup | tombol dilepas |
keypress | API lama untuk character input |
event.key | nama/nilai tombol |
event.code | kode posisi tombol keyboard |
event.keyCode | kode numerik lama/deprecated |
document.addEventListener() | mendengarkan keyboard secara global |
classList.add() | menambahkan class |
classList.remove() | menghapus class |
classList.contains() | mengecek apakah class ada |
45. Tiga classList method yang sekarang kamu punya
classList
│
┌────────────┼────────────┐
↓ ↓ ↓
add remove contains
↓ ↓ ↓
tambah hapus cek
Contoh:
element.classList.add("hide");
element.classList.remove("hide");
element.classList.contains("hide");
Yang ketiga mengembalikan:
true
atau:
false
46. Kesimpulan besar lecture
Kalau disederhanakan, instructor sedang mengajarkan pola:
1. Dengarkan keyboard
↓
2. Tangkap event object
↓
3. Cari tahu tombolnya
↓
4. Gunakan condition
↓
5. Jalankan aksi
Contoh:
document.addEventListener("keydown", function (event) {
if (event.key === "Enter") {
hideModal();
}
});
Dibaca manusia:
“JavaScript, dengarkan semua tombol keyboard. Kalau tombol yang ditekan adalah Enter, jalankan
hideModal().”
Dan karena hideModal():
function hideModal() {
modalDiv.classList.add("hide");
}
maka hasil akhirnya:
ENTER
↓
keydown
↓
event.key === "Enter"
↓
hideModal()
↓
classList.add("hide")
↓
Modal tersembunyi
🧠 Mental model yang perlu kamu ingat
Event sebelumnya:
CLICK
↓
button listener
↓
handler
Event sekarang:
KEYBOARD
↓
document listener
↓
keydown
↓
event object
↓
event.key
↓
if
↓
action
Dan jangan lupa perbedaan terakhir ini:
keydown → tombol ditekan
keyup → tombol dilepas
Untuk kode modern:
event.key === "Enter"
lebih disarankan daripada:
event.keyCode === 13
Sedangkan:
classList.contains("hide")
digunakan untuk mengecek kondisi class, bukan mengubahnya.
Jadi sekarang kamu punya tiga operasi penting:
add() // tambah
remove() // hapus
contains() // cek
Ini akan sering sekali muncul ketika nanti kamu mulai membuat UI yang interaktif dan responsive terhadap keyboard.