DOM: Event Listener
Membuat halaman hidup dengan event: addEventListener untuk click, input, submit, dan keyboard. Termasuk anatomi event object (target, key, preventDefault) dan kenapa onclick lama harus ditinggalkan.
Kenapa Event Adalah Jantung Interaktivitas?
Halaman HTML statis hanya bisa dibaca. Yang membuatnya menjadi APLIKASI adalah reaksi terhadap aksi user: klik, ketikan, scroll, submit form. Mekanismenya disebut event: browser "mengumumkan" bahwa sesuatu terjadi, dan kodemu "mendengarkan" pengumuman itu lewat event listener. Tanpa event, tidak ada tombol yang berfungsi, tidak ada form yang terkirim, tidak ada game yang bisa dimainkan.
addEventListener: Cara Modern
const btn = document.getElementById("tombol");
btn.addEventListener("click", () => {
console.log("Diklik!");
});Kenapa tidak pakai btn.onclick = ...? Karena properti onclick hanya menampung SATU fungsi dan menimpa yang lama. addEventListener bisa dipasang berkali-kali, bisa dilepas dengan removeEventListener, dan mendukung opsi lanjutan seperti once: true (jalan sekali lalu lepas otomatis).
Contoh sederhana memakai playground modul ini (ada <button id="tombol"> dan <p id="hasil">):
let n = 0;
const hasil = document.getElementById("hasil");
document.getElementById("tombol").addEventListener("click", () => {
n++;
hasil.textContent = "Diklik " + n + "x";
});Event yang Paling Sering Dipakai
// Setiap ada perubahan ketikan (ideal untuk live search & validasi)
input.addEventListener("input", (e) => {
console.log("Ketik:", e.target.value);
});
// Saat form dikirim (tombol submit atau Enter di input)
form.addEventListener("submit", (e) => {
e.preventDefault(); // WAJIB: cegah reload halaman!
console.log("Form dikirim:", new FormData(form).get("nama"));
});
// Perubahan nilai yang sudah "final" (pilih dropdown, checkbox)
select.addEventListener("change", (e) => {
console.log("Pilihan:", e.target.value);
});Bedakan input vs change: input menyala TIAP karakter diketik (cocok untuk live preview), change menyala setelah nilai dikomit (cocok untuk dropdown dan checkbox).
Contoh realistis: live preview plus penghitung karakter seperti di Twitter.
const input = document.getElementById("nama");
const preview = document.getElementById("hasil");
const sisa = document.getElementById("sisa");
input.addEventListener("input", (e) => {
const teks = e.target.value;
preview.textContent = teks || "(kosong)";
const kurang = 20 - teks.length;
sisa.textContent = kurang >= 0 ? `Sisa ${kurang} karakter` : "Kepanjangan!";
sisa.style.color = kurang >= 0 ? "green" : "red";
});Event Object: Kotak Info Setiap Kejadian
Setiap listener menerima satu parameter event (biasa dinamai e atau event) berisi detail kejadian:
document.getElementById("tombol").addEventListener("click", (e) => {
console.log(e.type); // "click"
console.log(e.target); // elemen yang diklik
console.log(e.clientX, e.clientY); // posisi mouse
});
document.addEventListener("keydown", (e) => {
console.log(e.key); // "Enter", "a", "Escape"
if (e.key === "Enter") console.log("Enter ditekan!");
if (e.ctrlKey && e.key === "s") {
e.preventDefault(); // cegah dialog save browser
console.log("Simpan custom!");
}
});Tiga properti/method yang wajib dikuasai: e.target (siapa pemicunya), e.preventDefault() (batalkan perilaku bawaan browser seperti reload form atau navigasi link), dan e.key untuk keyboard.
Contoh realistis: tombol "back to top" plus shortcut keyboard.
window.addEventListener("scroll", () => {
const btn = document.getElementById("keAtas");
btn.style.display = window.scrollY > 300 ? "block" : "none";
});
document.addEventListener("keydown", (e) => {
if (e.key === "/" && document.activeElement.tagName !== "INPUT") {
e.preventDefault();
document.getElementById("cari").focus(); // "/" fokus ke search, ala GitHub
}
});Jebakan Umum
- Lupa
e.preventDefault()di handlersubmit: halaman reload dan semua state JS hilang. Ini error paling klasik form. - Memasang listener ke elemen yang belum ada (null) karena script jalan duluan. Pastikan seleksi berhasil sebelum
addEventListener. removeEventListenerbutuh REFERENSI fungsi yang sama persis. Listener berupa arrow function anonim tidak bisa dilepas. Simpan dulu:const fn = () => {...}; el.addEventListener("click", fn);.- Memasang listener
scrollatauinputyang berat tanpa throttle/debounce membuat halaman lag karena event menyala puluhan kali per detik.
Ringkasan
Event adalah cara halaman mendengar user: pasang dengan addEventListener("nama-event", handler), baca detailnya dari event object (target, key, value), dan batalkan perilaku bawaan dengan preventDefault() saat perlu (terutama form submit). Tinggalkan onclick lama, dan untuk ratusan elemen serupa jangan pasang ratusan listener: itu tugas modul berikutnya, event delegation.
export default function App(): JSX.Element { return <h1>Hello world</h1> }
Tantangan
Live Preview
Tambahkan input teks dan p#preview di HTML? Tidak bisa ubah HTML, jadi buat input dengan createElement, append ke body. Setiap "input", tampilkan nilainya di #hasil. Live preview adalah pola UX standar di dunia nyata: editor markdown, kolom komentar, dan form pendaftaran semuanya memberi umpan balik instan tiap user mengetik.
<!doctype html> <html> <head> <meta charset="utf-8" /> </head> <body> <h1>Halo JS</h1> <p>Buka console preview untuk melihat output.</p> <script src="index.js"></script> </body> </html>