Event adalah sinyal yang dikirim browser ketika sesuatu terjadi — pengguna klik tombol, mengetik di input, menggerakkan mouse, menekan tombol keyboard, halaman selesai dimuat, dan ratusan event lainnya. Event Handling adalah cara JavaScript merespons event-event tersebut dan menjalankan kode yang sesuai.
addEventListener — Cara Modern Menangani Event
const tombol = document.querySelector("#tombol-kirim");
// addEventListener(namaEvent, callbackFunction)
tombol.addEventListener("click", function(event) {
console.log("Tombol diklik!");
console.log(event); // objek Event berisi detail event
});
// Dengan arrow function
tombol.addEventListener("click", (e) => {
console.log("Diklik!", e.target); // e.target = elemen yang di-klik
});
// Hapus event listener
function handleClick() { console.log("klik"); }
tombol.addEventListener("click", handleClick);
tombol.removeEventListener("click", handleClick); // harus referensi fungsi yang sama
Jenis-Jenis Event yang Umum
Mouse Events
const box = document.querySelector(".box");
box.addEventListener("click", e => console.log("klik"));
box.addEventListener("dblclick", e => console.log("double klik"));
box.addEventListener("mouseenter", e => console.log("mouse masuk"));
box.addEventListener("mouseleave", e => console.log("mouse keluar"));
box.addEventListener("mousemove", e => {
console.log(`Posisi: ${e.clientX}, ${e.clientY}`);
});
box.addEventListener("contextmenu", e => {
e.preventDefault(); // cegah menu kanan bawaan browser
console.log("klik kanan");
});
Keyboard Events
document.addEventListener("keydown", e => {
console.log(`Tombol ditekan: ${e.key}`);
console.log(`Kode: ${e.code}`);
// Cek kombinasi tombol
if (e.ctrlKey && e.key === "s") {
e.preventDefault(); // cegah save browser
simpanData();
}
if (e.key === "Escape") tutupModal();
});
document.addEventListener("keyup", e => console.log("tombol dilepas"));
document.addEventListener("keypress",e => console.log("karakter diketik")); // deprecated
Form Events
const form = document.querySelector("form");
const input = document.querySelector("input");
form.addEventListener("submit", e => {
e.preventDefault(); // PENTING: cegah reload
const data = new FormData(form);
console.log(Object.fromEntries(data));
});
input.addEventListener("input", e => console.log("nilai berubah:", e.target.value));
input.addEventListener("change", e => console.log("blur setelah berubah"));
input.addEventListener("focus", e => console.log("input difokus"));
input.addEventListener("blur", e => console.log("focus hilang"));
Window dan Document Events
// Halaman selesai dimuat sepenuhnya (termasuk gambar)
window.addEventListener("load", () => console.log("semua resource dimuat"));
// DOM siap, gambar belum tentu (lebih cepat dari load)
document.addEventListener("DOMContentLoaded", () => {
console.log("DOM siap");
initApp();
});
// Scroll
window.addEventListener("scroll", () => {
const scrollY = window.scrollY;
if (scrollY > 300) navbar.classList.add("sticky");
});
// Resize
window.addEventListener("resize", () => {
console.log(`Lebar: ${window.innerWidth}, Tinggi: ${window.innerHeight}`);
});
// Sebelum meninggalkan halaman
window.addEventListener("beforeunload", e => {
e.preventDefault();
e.returnValue = ""; // trigger dialog "tinggalkan halaman?"
});
Objek Event
Setiap event listener menerima objek Event yang berisi informasi detail:
document.querySelector("a").addEventListener("click", function(e) {
e.preventDefault(); // cegah perilaku default (navigasi link)
e.stopPropagation(); // hentikan event bubble ke parent
console.log(e.type); // "click"
console.log(e.target); // elemen yang memicu event
console.log(e.currentTarget); // elemen yang punya listener
console.log(e.timeStamp); // waktu event terjadi
});
Event Bubbling dan Capturing
Event di DOM berjalan dalam dua fase:
- Capturing (atas ke bawah): dari document ke target
- Bubbling (bawah ke atas): dari target kembali ke document
<div id="luar">
<div id="dalam">
<button id="tombol">Klik</button>
</div>
</div>
// Secara default: bubbling (dari dalam ke luar)
document.querySelector("#tombol").addEventListener("click", () => console.log("tombol"));
document.querySelector("#dalam").addEventListener("click", () => console.log("dalam"));
document.querySelector("#luar").addEventListener("click", () => console.log("luar"));
// Output saat klik tombol: "tombol" → "dalam" → "luar"
// Hentikan bubbling
document.querySelector("#dalam").addEventListener("click", e => {
e.stopPropagation(); // event tidak naik ke #luar
console.log("dalam — event berhenti di sini");
});
// Capturing — parameter ketiga: true
document.querySelector("#luar").addEventListener("click", () => {
console.log("luar (capturing)");
}, true);
// Output: "luar" → "dalam" → "tombol"
Event Delegation — Satu Listener untuk Banyak Elemen
Daripada menambahkan listener ke setiap elemen, pasang satu listener di parent dan manfaatkan bubbling:
// KURANG EFISIEN — listener di setiap item
document.querySelectorAll(".btn-hapus").forEach(btn => {
btn.addEventListener("click", hapusItem);
});
// LEBIH BAIK — event delegation
document.querySelector("#daftar").addEventListener("click", function(e) {
// Cek apakah yang diklik adalah tombol hapus
if (e.target.matches(".btn-hapus")) {
const li = e.target.closest("li");
li.remove();
}
// Cek tombol edit
if (e.target.matches(".btn-edit")) {
const id = e.target.dataset.id;
editItem(id);
}
});
Keuntungan: bekerja untuk elemen yang ditambahkan secara dinamis setelah listener dipasang.
Debounce dan Throttle
Event seperti scroll, resize, dan input bisa trigger ratusan kali per detik. Debounce dan throttle membatasi frekuensi eksekusi:
// Debounce — tunggu N ms setelah event terakhir
function debounce(fn, delay) {
let timer;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
const cariProduk = debounce(function(e) {
console.log("Mencari:", e.target.value);
// panggil API di sini
}, 400);
document.querySelector("#search").addEventListener("input", cariProduk);
// Throttle — eksekusi maksimal sekali per N ms
function throttle(fn, limit) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
fn.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
window.addEventListener("scroll", throttle(() => {
console.log("Scroll position:", window.scrollY);
}, 200));
Kesimpulan
Event handling adalah fondasi dari semua interaktivitas di web. Dengan addEventListener, memahami bubbling, dan teknik event delegation, kamu bisa membangun UI yang responsif dan efisien.
Di artikel berikutnya, kita masuk ke AJAX dan Fetch API — cara JavaScript berkomunikasi dengan server tanpa reload halaman.
Kiki/🎮🍉⌨️🍩💻