Javascript DOM Event Handling Form Interaction
Definisi
DOM (Document Object Model) adalah representasi struktur HTML yang bisa diakses dan dimanipulasi dengan JavaScript. Melalui DOM, JavaScript dapat memilih elemen, membaca isi, mengubah atribut, menambah atau menghapus node, dan merespons interaksi pengguna.
Event handling adalah mekanisme untuk merespons aksi seperti klik, input, submit, focus, keydown, dan change. Saat event terjadi, browser membangkitkan event object dan mengirimkannya ke handler yang terdaftar.
Kenapa penting
Hampir semua interaksi web modern bergantung pada tiga hal ini:
- memilih elemen yang tepat
- merespons event dengan alur yang benar
- mengelola form tanpa merusak perilaku bawaan browser
Kalau alurnya tidak dipahami, bug yang muncul biasanya bentuknya sama:
- tombol tidak bekerja karena selector salah
- handler terpanggil dua kali karena bubbling tidak diperhitungkan
- form reload karena
preventDefault()tidak dipakai - daftar dinamis sulit dikelola karena listener dipasang satu per satu
Cara memilih elemen
JavaScript mengambil elemen DOM lewat API document dan Element.
Selector umum
document.getElementById(id)untuk satu elemen berdasarkaniddocument.querySelector(selector)untuk satu elemen pertama yang cocokdocument.querySelectorAll(selector)untuk semua elemen yang cocokelement.matches(selector)untuk mengecek apakah node cocok dengan selector tertentuelement.closest(selector)untuk naik ke ancestor terdekat yang cocok
Kapan pakai yang mana
- Pakai
getElementById()kalau targetnya unik dan stabil. - Pakai
querySelector()kalau perlu fleksibilitas selector CSS. - Pakai
querySelectorAll()kalau ingin koleksi elemen lalu diiterasi. - Pakai
closest()saat event delegation perlu mencari konteks dari target event.
Contoh
const form = document.querySelector('#signup-form');
const submitButton = document.getElementById('submit-btn');
const fields = document.querySelectorAll('.form-field');Catatan penting
Selector yang baik itu bukan yang paling pendek, tetapi yang paling stabil dan mudah dirawat. Kalau struktur halaman sering berubah, selector berbasis class presentasional biasanya lebih rapuh dibanding id, data-*, atau struktur semantik yang jelas.
Cara kerja event
Saat event terjadi, browser membuat event object, menentukan target, lalu menjalankan listener sesuai fase event.
Tiga fase utama
- Capturing phase: event bergerak dari
window/documentturun ke target. - Target phase: event mencapai elemen target.
- Bubbling phase: event naik dari target ke ancestor.
Secara default, banyak event umum seperti click akan bubbling. Itu sebabnya satu listener di container bisa menangkap klik dari child di dalamnya.
Mermaid: alur event
Bubbling dan capturing
Bubbling
Bubbling adalah pergerakan event dari elemen target naik ke parent, lalu ke parent di atasnya, sampai ke root.
Ini berguna karena:
- satu listener di container bisa menangani banyak child
- listener lebih sedikit
- elemen dinamis lebih mudah ditangani
Contoh:
<ul id="menu">
<li><button class="item">A</button></li>
<li><button class="item">B</button></li>
</ul>document.querySelector('#menu').addEventListener('click', (event) => {
if (event.target.matches('.item')) {
console.log('Item diklik:', event.target.textContent);
}
});Capturing
Capturing berjalan dari luar ke dalam. Fase ini lebih jarang dipakai, tetapi berguna ketika kamu perlu mengamati event sebelum child menanganinya.
Untuk memakai capturing, listener didaftarkan dengan opsi { capture: true }.
container.addEventListener('click', handleClick, { capture: true });Kapan capturing dipakai
Capturing dipakai saat:
- kamu perlu observasi awal sebelum event sampai ke target
- ada kebutuhan audit, logging, atau kontrol khusus di level container atas
- kamu ingin membedakan alur yang sangat spesifik dari bubbling biasa
Dalam praktik sehari-hari, bubbling jauh lebih sering dipakai daripada capturing.
Mermaid: bubbling vs capturing
Menghentikan atau membatasi event
Ada beberapa metode yang sering dipakai saat event perlu dikontrol.
preventDefault()
preventDefault() mencegah perilaku bawaan browser.
Contoh perilaku bawaan:
- form melakukan submit dan reload halaman
- link berpindah halaman
- checkbox atau radio menjalankan perilaku defaultnya
form.addEventListener('submit', (event) => {
event.preventDefault();
console.log('Validasi atau request AJAX di sini');
});Gunakan preventDefault() hanya kalau kamu memang ingin mengganti perilaku bawaan. Kalau tidak, biarkan browser bekerja seperti semestinya.
stopPropagation()
stopPropagation() menghentikan event agar tidak lanjut ke ancestor.
Ini berguna kalau parent punya listener global, tetapi child harus diproses sendiri tanpa memicu handler container.
button.addEventListener('click', (event) => {
event.stopPropagation();
console.log('Hanya button ini yang diproses');
});stopImmediatePropagation()
stopImmediatePropagation() lebih kuat: event berhenti, dan listener lain pada elemen yang sama juga tidak dijalankan.
Pakai ini sangat hati-hati karena efeknya cukup agresif.
Interaksi form
Form adalah area paling umum untuk menggabungkan DOM selection, event handling, dan default behavior.
Event penting pada form
submit: saat form dikiriminput: setiap perubahan nilai saat mengetikchange: saat nilai dianggap berubah dan dikonfirmasi browserfocusdanblur: saat elemen mendapat atau kehilangan fokusinvalid: saat validasi native gagal
Alur dasar submit
- user mengisi field
- browser memicu event input/change
- user menekan tombol submit atau Enter
- browser memicu event submit
- handler bisa memvalidasi data
- jika perlu,
preventDefault()dipakai untuk mencegah reload - data dikirim manual lewat fetch/AJAX atau diproses lokal
Contoh submit form
const form = document.querySelector('#contact-form');
form.addEventListener('submit', async (event) => {
event.preventDefault();
const formData = new FormData(form);
const payload = Object.fromEntries(formData.entries());
if (!payload.email) {
console.log('Email wajib diisi');
return;
}
await fetch('/api/contact', {
method: 'POST',
body: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json',
},
});
});Validasi form
Ada dua lapis validasi yang umum dipakai:
- validasi native browser:
required,type="email",minlength,pattern - validasi JavaScript: aturan tambahan yang tidak bisa ditangani HTML saja
Kalau validasi native cukup, jangan tambah JavaScript yang tidak perlu. Browser sudah punya banyak perilaku form yang matang.
Membaca nilai field
const email = document.querySelector('#email').value;
const isChecked = document.querySelector('#terms').checked;
const selectedValue = document.querySelector('#role').value;Kapan event delegation dipakai
Event delegation adalah pola menaruh listener di parent/container, lalu memeriksa event.target atau closest() untuk menentukan elemen mana yang sebenarnya diproses.
Dipakai kalau
- banyak elemen child yang sejenis
- elemen child sering ditambah atau dihapus secara dinamis
- ingin mengurangi jumlah listener
- ingin mengelola UI daftar, menu, tabel, kartu, atau item hasil render ulang
Contoh delegation
const list = document.querySelector('#todo-list');
list.addEventListener('click', (event) => {
const removeButton = event.target.closest('[data-action="remove"]');
if (!removeButton) return;
const item = removeButton.closest('.todo-item');
if (item) item.remove();
});Jangan pakai delegation kalau
- event tidak bubbling
- butuh kontrol sangat spesifik per elemen
- target yang diproses sangat sedikit dan statis, sehingga listener langsung lebih jelas
Kenapa delegation efektif
Delegation memindahkan kompleksitas dari banyak listener menjadi satu alur pemeriksaan target. Hasilnya biasanya lebih ringan, lebih mudah dirawat, dan lebih cocok untuk UI yang berubah setelah render.
Catatan implementasi
- Selalu cek apakah selector benar-benar menemukan elemen sebelum memasang listener.
- Gunakan
DOMContentLoadedatau letakkan script di akhir body kalau elemen belum tentu sudah ada saat script berjalan. - Gunakan
event.currentTargetuntuk elemen tempat listener dipasang, danevent.targetuntuk elemen asal event. - Kalau target bisa berupa child dalam tombol atau card, gunakan
closest()agar hit detection lebih stabil. - Jangan mencegah default submit tanpa alasan; form native sering lebih aman dan lebih aksesibel.
- Untuk form kompleks, kombinasikan validasi native, feedback visual, dan submit handler yang jelas.
- Kalau UI memuat banyak item dinamis, delegation biasanya lebih murah daripada menempelkan listener ke setiap node.
Istilah
- DOM: representasi objek dari struktur dokumen HTML.
- Event: sinyal dari browser bahwa sesuatu terjadi.
- Target: elemen tempat event pertama kali terjadi.
- Capturing: fase event dari luar ke dalam.
- Bubbling: fase event dari target ke luar.
- Default behavior: perilaku bawaan browser.
- Event delegation: pola menangani event lewat ancestor.
- FormData: API untuk membaca data form sebagai pasangan key-value.
Referensi terkait
- DOM dipakai untuk memilih dan memanipulasi elemen.
- Event bubbling membantu delegation.
preventDefault()dipakai saat perilaku native perlu diganti.closest()sering dipakai untuk menangani target dalam struktur yang bersarang.