DataLens

DOM: memilih dan mengubah elemen

Temukan elemen dengan querySelector, ubah teks, class, dan atributnya, buat dan hapus elemen, serta tampilkan daftar data dengan aman tanpa jebakan innerHTML.

Level: Menengah · 8 menit baca

Latihan modul ini

Soal-soal untuk pelajaran ini berjalan di browser-mu dan langsung mengecek jawabanmu.

Idenya

Saat browser memuat halaman, ia mengubah HTML menjadi pohon objek yang disebut DOM (Document Object Model). JavaScript bisa membaca dan mengubah pohon itu, dan halamannya langsung diperbarui. Begitulah penghitung keranjang naik, daftar tersaring saat kamu mengetik, atau pesan error muncul di bawah field formulir. Semua hal interaktif di browser bermuara pada "temukan sebuah elemen, ubah elemen itu".

Contoh-contoh di modul ini membangun halaman kecilnya sendiri lebih dulu dengan document.body.innerHTML, sehingga masing-masing bisa berjalan sendiri.

Memilih elemen

Sebelum kamu bisa mengubah apa pun di halaman, kamu harus menemukannya. Ini daftar produk kecil. Baris pertama membangun halamannya (di situs sungguhan, isinya sudah ada di HTML), dan sisanya mencari elemen di dalamnya memakai CSS selector yang sudah kamu kenal:

document.body.innerHTML = `
  <h1 id="title">Toko Kita</h1>
  <ul class="products">
    <li class="product" data-id="1">Arabica Gayo</li>
    <li class="product sold-out" data-id="2">Toraja Kalosi</li>
    <li class="product" data-id="3">Kintamani</li>
  </ul>`;

const title = document.querySelector("#title");
const first = document.querySelector(".product");
const all = document.querySelectorAll(".product");
const missing = document.querySelector(".does-not-exist");

console.log(title.textContent);
console.log(first.textContent, all.length);
console.log(missing);
Toko Kita
Arabica Gayo 3
null

Hasil null adalah bug DOM klasik: document.querySelector("#tilte").textContent crash dengan "Cannot read properties of null". Cek selector-mu saat melihat error itu.

Mengubah teks, class, dan atribut

Begitu kamu punya sebuah elemen, kamu bisa mengubahnya. Saat sebuah produk habis, labelnya harus berbunyi "Sold out" dan tampil keabu-abuan. Saat kamu menambahkan sesuatu ke keranjang, penghitung kecil di pojok harus naik. Masing-masing adalah perubahan kecil pada teks, class, atau atribut sebuah elemen:

document.body.innerHTML = `<p class="stock">In stock</p><a class="link" href="/old">Details</a><span id="cart-count">0</span>`;

const stock = document.querySelector(".stock");
stock.textContent = "Sold out";
stock.classList.add("sold-out");
stock.classList.remove("stock");
console.log(stock.className, stock.classList.contains("sold-out"));

const link = document.querySelector(".link");
link.setAttribute("href", "/product/2");
console.log(link.getAttribute("href"));

const counter = document.querySelector("#cart-count");
counter.textContent = Number(counter.textContent) + 1;
console.log(counter.textContent);
sold-out true
/product/2
1

Atribut data

Atribut data-* menyimpan informasimu sendiri di elemen, yang bisa dibaca lewat element.dataset:

document.body.innerHTML = `<li class="product" data-id="7" data-price="95000">Arabica Gayo</li>`;
const item = document.querySelector(".product");
console.log(item.dataset.id, item.dataset.price);
item.dataset.inCart = "true";
console.log(item.outerHTML);
7 95000
<li class="product" data-id="7" data-price="95000" data-in-cart="true">Arabica Gayo</li>

data-in-cart di HTML menjadi dataset.inCart di JavaScript (tanda strip menjadi camelCase).

Membuat, menambahkan, dan menghapus elemen

Kadang elemennya belum ada. Saat pelanggan menambahkan produk, daftar keranjang butuh baris baru untuk masing-masing, dan saat mereka membuang sesuatu, barisnya harus hilang. Kamu membangun elemen dari data lalu menambahkannya ke halaman:

document.body.innerHTML = `<ul id="cart"></ul>`;
const list = document.querySelector("#cart");

const items = [{ name: "Arabica Gayo", qty: 2 }, { name: "French Press", qty: 1 }];
for (const item of items) {
  const li = document.createElement("li");
  li.textContent = item.name + " × " + item.qty;
  li.classList.add("cart-item");
  list.append(li);
}
console.log(list.children.length, list.lastElementChild.textContent);

list.firstElementChild.remove();
console.log(list.children.length);
2 French Press × 1
1

createElement membuat elemen baru, append menambahkannya di akhir sebuah induk (prepend untuk di awal), dan remove() mengeluarkan elemen dari halaman.

innerHTML: praktis dan berbahaya

element.innerHTML = "..." mengganti isi sebuah elemen dengan HTML yang di-parse dari string. Ini praktis untuk markup tetap milikmu sendiri, seperti di contoh-contoh di atas. Jangan pernah memakainya dengan data dari pengguna atau API:

document.body.innerHTML = `<div id="review"></div>`;
const review = document.querySelector("#review");
const userText = "<img src=x onerror=alert('hacked')>";

review.textContent = userText;                     // safe: shown as text
console.log(review.innerHTML);
&lt;img src=x onerror=alert('hacked')&gt;

Dengan innerHTML = userText, browser akan membuat gambar itu dan menjalankan kode penyerang: serangan cross-site scripting (XSS). Dengan textContent, string yang sama ditampilkan sebagai teks yang tidak berbahaya. Bangun elemen dengan createElement + textContent saat ada bagian konten yang berasal dari luar kodemu.

Ide utama

querySelector/querySelectorAll untuk menemukan elemen (null berarti tidak ada yang cocok); textContent, classList dan setAttribute/dataset untuk mengubahnya; createElement + append untuk menambah, remove() untuk menghapus. Gunakan textContent, jangan pernah innerHTML, untuk data yang bukan milikmu.

Mengapa ini penting untuk kode yang bersih

Jaga kode DOM tetap tipis: hitung data di function biasa, lalu biarkan satu function kecil yang me-render data itu ke halaman. Toggle class alih-alih mengatur inline style, supaya tampilan tetap di CSS. Dan pilih elemen sekali, di dekat bagian atas, dengan nama yang jelas (const cartList = ...), alih-alih mengulang selector di seluruh kode.

Rangkuman

Latihan modul ini

Soal-soal untuk pelajaran ini berjalan di browser-mu dan langsung mengecek jawabanmu.

Berikutnya: Event dan event listener →