DOM Advanced — JavaScript

Dasar DOM ngajarin kamu cara baca-tulis elemen satu-satu. Tapi pas aplikasi membesar — list to-do dengan 100 item, chat dengan ribuan pesan — pendekatan satu-sa

Dasar DOM ngajarin kamu cara baca-tulis elemen satu-satu. Tapi pas aplikasi membesar — list to-do dengan 100 item, chat dengan ribuan pesan — pendekatan satu-satu jadi lambat dan ribet. DOM Advanced kasih kamu tools profesional: traversal antar elemen, manipulasi class lewat classList, dan pattern paling penting — event delegation yang ngirit listener via satu listener di parent.

💡 Aturan performa #1. Querying DOM itu mahal. document.querySelector() di dalam loop yang jalan 1000 kali = bottleneck. Cache query sekali di luar loop, terus pake variabelnya. Trick simpel yang bisa bikin app kamu 10x lebih responsive.

Membuat dan menambahkan elemen:

const li = document.createElement("li");
li.textContent = "Item Baru";
document.querySelector("ul").appendChild(li);

Menghapus elemen:

const item = document.querySelector("#hapus-ini");
item.parentNode.removeChild(item);
// atau cara modern:
item.remove();

DOM Traversal — navigasi antar elemen:

const elemen = document.querySelector(".aktif");

elemen.parentNode;            // elemen induk
elemen.children;              // semua anak langsung
elemen.nextElementSibling;    // saudara berikutnya
elemen.previousElementSibling; // saudara sebelumnya

classList — kelola class CSS:

const box = document.querySelector(".box");

box.classList.add("aktif");      // tambah class
box.classList.remove("aktif");   // hapus class
box.classList.toggle("aktif");   // toggle (tambah/hapus)
box.classList.contains("aktif"); // cek apakah ada (true/false)

Event Delegation — pasang event di parent:

const menu = document.querySelector("ul");

menu.addEventListener("click", function(event) {
  if (event.target.tagName === "LI") {
    // toggle class "aktif" pada li yang diklik
    event.target.classList.toggle("aktif");
  }
});

Event delegation efisien karena hanya butuh satu event listener di parent, bukan satu per anak. Ini juga otomatis bekerja untuk elemen yang ditambahkan secara dinamis.

🎭 Analogi sehari-hari

Event delegation = satu satpam di pintu gerbang kantor yang nanya semua yang masuk: "kamu mau ke ruangan mana?". Lebih efisien dari pasang satpam di setiap ruangan. Plus kalau ada ruangan baru dibuat (elemen baru), satpam pintu otomatis melayani.

⚠️ Jebakan yang sering ditemui

1. querySelector return null kalau tidak ketemu.

const x = document.querySelector(".tidak-ada");
x.textContent = "halo";   // ❌ TypeError: Cannot read properties of null
x?.textContent && (x.textContent = "halo");   // ✅ optional chaining

2. event.target vs event.currentTarget — beda!

parent.addEventListener("click", e => {
  e.target;          // elemen yang DIKLIK (bisa anak)
  e.currentTarget;   // elemen yang PASANG listener (parent)
});

3. innerHTML = "..." BAHAYA dengan input user — XSS.

div.innerHTML = userInput;     // ❌ kalau userInput = "<script>...</script>"
div.textContent = userInput;   // ✅ aman, di-escape otomatis

4. Query DOM di loop = lambat.

for (let i = 0; i < 100; i++) {
  document.querySelector("#x").style.color = "red";  // ❌ query 100x
}
const x = document.querySelector("#x");
for (let i = 0; i < 100; i++) {
  x.style.color = "red";   // ✅ query sekali
}

5. appendChild dengan elemen yang sudah ada di DOM = pindahkan, bukan duplikat.

🎯 querySelector vs getElementById vs querySelectorAll — pilih yang mana?

  • Cari satu elemen by IDgetElementById("nav") (tercepat, 5x faster dari querySelector)
  • Cari satu elemen by class/tag/attr/kombinasiquerySelector(".btn") (CSS selector flexible)
  • Cari MULTIPLE elemenquerySelectorAll(".item") (return NodeList — perlu spread [...] atau forEach)
  • Cari child dari parent specificparent.querySelector(".child") (scoped, lebih efisien dari global)
  • Live update collectiongetElementsByClassName (auto-update saat DOM berubah, jarang dipake)

Aturan modern: querySelector 99% kasus karena flexible. getElementById cuma kalau perf-critical loop. querySelectorAll return STATIC NodeList — gak update otomatis (beda dari getElementsByClassName).

TL;DR: DOM Advanced = traversal (parentNode/children/nextElementSibling), classList (add/remove/toggle/contains), dan event delegation (1 listener di parent ganti N listener di anak — bonus: auto-handle elemen yang nambah dinamis). event.target = yang diklik, event.currentTarget = yang pasang listener. Cache query di luar loop (jangan query 100x). Hindari innerHTML dengan user input (XSS) — pakai textContent.

Yang akan kamu pelajari