mahirdomeventpolaMahir3 mnt baca

Event Delegasi

Teknik efisien menangani event banyak elemen dengan satu listener di parent memakai event bubbling.

Satu listener untuk banyak elemen

Bayangkan list dengan 100 item, tiap item butuh handler klik. Memasang 100 listener boros memori dan merepotkan. Event delegasi memasang SATU listener di parent, lalu mengenali item mana yang diklik lewat e.target.

Cara kerja: event bubbling

Event di DOM "menggelembung" ke atas: klik pada li akan memicu handler di li, lalu ul, lalu body, sampai document. Delegasi memanfaatkan ini:

javascript
let ul = document.querySelector("ul");

ul.addEventListener("click", (e) => {
  // pastikan yang diklik adalah li, bukan ul-nya
  let li = e.target.closest("li");
  if (!li) return;
  console.log("Klik: " + li.textContent);
  li.classList.toggle("selesai");
});

Satu listener menangani semua li, sekarang dan nanti.

Keunggulan untuk elemen dinamis

Elemen yang ditambahkan belakangan otomatis ikut ter-cover karena listener ada di parent yang sudah ada sejak awal:

javascript
let ul = document.querySelector("ul");

ul.addEventListener("click", (e) => {
  let tombolHapus = e.target.closest(".hapus");
  if (tombolHapus) {
    tombolHapus.closest("li").remove();
  }
});

// item baru yang ditambahkan nanti tetap bisa dihapus
let li = document.createElement("li");
li.innerHTML = 'Belajar delegasi <button class="hapus">x</button>';
ul.appendChild(li);

Tanpa delegasi, kamu harus memasang listener baru setiap kali menambah item. Itu rawan lupa dan bocor memori.

Kapan tidak cocok?

Delegasi kurang pas untuk event yang tidak bubble (focus, blur, mouseenter tidak menggelembung) atau saat tiap elemen butuh perilaku yang sangat berbeda. Untuk kasus itu, listener langsung lebih jelas.

Catatan teknis: Selalu validasi e.target dengan closest() sebelum dipakai. Klik bisa jatuh di elemen anak yang tidak terduga (misalnya span di dalam button). Pola if (!el) return di awal handler delegasi mencegah error dan perilaku aneh.

Studi kasus: todo list dinamis

Delegasi membuat todo list yang itemnya bisa tambah dan hapus tanpa pasang listener baru:

javascript
let ul = document.querySelector("#todo");

ul.addEventListener("click", (e) => {
  let tombolHapus = e.target.closest(".hapus");
  if (tombolHapus) {
    tombolHapus.closest("li").remove();
    return;
  }
  let item = e.target.closest("li");
  if (item) item.classList.toggle("selesai");
});

function tambahTodo(teks) {
  let li = document.createElement("li");
  li.innerHTML = '<span></span><button class="hapus">x</button>';
  li.querySelector("span").textContent = teks; // aman dari XSS
  ul.appendChild(li); // otomatis ter-cover listener!
}

Satu listener menangani klik selesai dan hapus untuk semua item, termasuk yang belum ada saat halaman dimuat. Perhatikan innerHTML hanya untuk struktur tetap, teks pengguna tetap lewat textContent.

Kesimpulan

Delegasi = satu listener di parent + e.target.closest() untuk identifikasi. Ini pola wajib untuk list dinamis, tabel, dan menu. Lebih hemat, lebih rapi, dan otomatis menangani elemen baru.