tutorial, javascript,

JavaScript Event Handling: Respons terhadap Interaksi Pengguna

Kiki/🎮🍉⌨️🍩💻 Kiki/🎮🍉⌨️🍩💻 Oct 08, 2026 · 10 mins read
JavaScript Event Handling: Respons terhadap Interaksi Pengguna
Share this

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:

  1. Capturing (atas ke bawah): dari document ke target
  2. 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/🎮🍉⌨️🍩💻
Written by Kiki/🎮🍉⌨️🍩💻
hello I'm friend K.