Panggil event.stopPropagation() di handler elemen anak untuk cara mengatasi event bubbling javascript tidak diinginkan. Tanpa itu, klik tombol di dalam card ikut menjalankan listener click milik card, modal, atau li karena event berjalan dari target ke atas.
Penyebab Event Bubbling Terpicu ke Elemen Induk
Browser menjalankan event dalam tiga fase: capturing turun dari window ke target, lalu target, lalu bubbling naik kembali ke induk. addEventListener memakai fase bubbling secara default.
Kasus umum yang sering bermasalah:
- Tombol hapus di dalam card yang bisa diklik untuk membuka detail.
- Tombol tutup atau konten di dalam modal yang klik backdrop-nya menutup modal.
- Tombol kecil di dalam
liatauformyang punya handler sendiri.
Tanda handler induk ikut jalan:
- Klik tombol anak membuka detail card sekaligus menghapus item.
- Klik isi modal malah menutup modal.
- Satu klik memicu dua aksi berurutan, anak dulu lalu induk.
Tabel Kondisi, Penyebab, dan Solusi Cepat
Kondisi | Penyebab | Solusi
Klik tombol anak menjalankan aksi card | Event naik ke listener induk | Tambahkan stopPropagation() di handler anak
Klik isi modal menutup modal | Listener backdrop menerima bubble | Cek event.target atau hentikan bubble dari konten
Handler tidak jalan sama sekali | Selector salah atau DOM belum siap | Periksa querySelector setelah DOM dimuat, bukan logic propagasi
Cara Memperbaiki Event Bubbling yang Tidak Diinginkan
Ikuti urutan ini agar tidak salah memblokir event lain:
- Temukan listener induk yang ikut terpanggil, misalnya di
.card. - Cek
event.targetuntuk elemen yang diklik danevent.currentTargetuntuk elemen pemilik listener. - Pasang
stopPropagation()hanya di handler anak. - Uji klik anak dan klik area induk secara terpisah.
Salah, klik tombol ikut membuka card:
document.querySelector(".card").addEventListener("click", () => {
openDetail();
});
document.querySelector(".delete-btn").addEventListener("click", () => {
deleteItem();
});
Benar, klik tombol berhenti di tombol:
document.querySelector(".delete-btn").addEventListener("click", (event) => {
event.stopPropagation();
deleteItem();
});
Pakai stopImmediatePropagation() bila satu elemen punya beberapa listener click dan listener berikutnya harus dibatalkan juga. Untuk daftar dinamis, pakai delegation dengan closest() agar satu listener di container bisa membedakan tombol anak dan area card.
Cara Mencegah Bubbling Kambuh di Elemen Dinamis
- Pasang listener di container terdekat, bukan di
documentuntuk semua hal. - Hindari listener ganda pada elemen yang dirender ulang, bersihkan dulu atau pakai delegation.
- Pastikan DOM siap sebelum
querySelector, panggil skrip di akhir body atau setelahDOMContentLoaded. - Gunakan
textContentbila hanya butuh teks, karena lebih aman daripadainnerHTML.
FAQ
Apakah stopPropagation menghentikan listener lain di elemen yang sama?
Tidak, gunakan stopImmediatePropagation() untuk menghentikan listener lain pada elemen yang sama.
Kapan memakai event.target dibanding event.currentTarget?
Pakai event.target untuk mengetahui elemen yang diklik, pakai event.currentTarget untuk elemen pemilik listener.
Apakah preventDefault bisa menghentikan bubbling?
Tidak, preventDefault() hanya membatalkan aksi bawaan browser dan event tetap naik ke induk.