Mengapa DOM ada
Bab 2 sampai 5 membuat halaman yang diam. Browser membaca HTML dan CSS, menampilkannya, lalu berhenti. Tidak ada yang berubah setelah halaman terbuka. Padahal halaman yang kamu pakai setiap hari hidup. Daftar tugas bertambah saat tombol ditekan, keranjang belanja menghitung ulang, tombol suka berubah warna. Perubahan itu dikerjakan JavaScript. Untuk itu JavaScript butuh sesuatu yang bisa digenggam, yaitu representasi halaman yang bisa dibaca dan ditulis program. Tanpa representasi itu, kode hanya bisa mencetak teks ke console. Representasi itu bernama DOM.
Apa itu DOM
DOM adalah Document Object Model, peta objek halaman yang disusun browser saat membaca HTML. Objek artinya bagian halaman yang bisa diprogram. Browser membaca file HTML dan membentuk pohon. Pohon adalah struktur bertingkat di mana satu elemen berada di dalam elemen lain. Setiap objek di pohon disebut node. Pintu masuknya bernama document, objek bawaan browser yang mewakili seluruh halaman. Lewat document, JavaScript bisa bertanya tentang halaman dan mengubahnya.
<h2 id="judul">Daftar belanja</h2>
<ul id="daftar">
<li>kopi</li>
</ul>
Browser menyusunnya berlapis. document di puncak, lalu html, lalu body. Di dalam body ada h2 dan ul. Di dalam ul ada li. Susunan ini tetap, dan JavaScript memakainya untuk menemukan elemen.
Memilih elemen
Sebelum mengubah sesuatu, kamu harus menunjuknya. document.querySelector adalah perintah untuk memilih satu elemen. Ia menerima satu selektor. Selektor adalah pola pencarian yang menyalin cara CSS memilih elemen, materi bab 3. Tanda pagar # memilih elemen dengan id tertentu, titik . memilih elemen dengan class tertentu, dan menulis nama tag seperti li memilih tag itu.
const judul = document.querySelector("#judul");
const daftar = document.querySelector("#daftar");
querySelector mengembalikan elemen pertama yang cocok. Kalau tidak ada yang cocok, ia mengembalikan null, nilai khusus yang berarti tidak ada. Untuk memilih semua elemen yang cocok sekaligus, pakai document.querySelectorAll. Hasilnya mirip array dan bisa diputar dengan forEach.
Mengubah isi dan atribut
Setelah terpilih, elemen bisa diubah. Properti textContent adalah isi teks elemen. Memberi nilai padanya langsung mengganti teks di halaman.
judul.textContent = "Daftar belanja minggu ini";
Elemen juga membawa atribut, informasi tambahan seperti id, class, dan href. Yang paling sering diubah adalah class, dan cara resminya lewat classList, daftar class milik elemen.
judul.classList.add("sorot"); // menambah class
judul.classList.remove("sorot"); // melepas class
judul.classList.toggle("sorot"); // menambah bila belum ada, melepas bila sudah
Ada juga innerHTML, pengganti textContent yang membaca teks sebagai HTML lengkap dengan tag. Berguna untuk menyisipkan markup, tapi berbahaya bila isinya berasal dari pengguna, karena orang lain bisa menyelundupkan kode lewat situ. Untuk teks biasa, selalu pakai textContent.
Membuat elemen baru
Memilih dan mengubah belum lengkap tanpa menambah. document.createElement membuat elemen baru yang belum menempel di halaman. appendChild menempelkannya sebagai anak terakhir dari elemen lain.
const item = document.createElement("li");
item.textContent = "teh";
daftar.appendChild(item);
Elemen juga bisa dilepas dengan remove(). Semua perubahan ini terjadi langsung pada halaman, dan pembaca melihat hasilnya seketika tanpa memuat ulang.
Analogi: silsilah keluarga
Satu gambar untuk semuanya. Bayangkan peta silsilah keluarga. document adalah leluhur paling tua yang menyimpan semua nama. Setiap elemen adalah anggota keluarga. Elemen yang membungkus elemen lain adalah orang tua, elemen di dalamnya adalah anak, dan h2 serta ul pada contoh tadi adalah saudara di bawah body. Memilih elemen sama dengan memanggil anggota lewat namanya, lewat id atau ciri lain pada selektor. Mengubah halaman sama dengan mengubah keadaan anggota itu. Ganti ucapannya dengan textContent. Ganti pakaiannya dengan classList. Hadirkan anggota baru dengan createElement dan appendChild.
Pasangan contoh
Kode di bawah menambah satu barang ke daftar belanja dan menyorot judulnya. Versi vanilla memerintah halaman langkah demi langkah. Versi React tidak menyentuh DOM sama sekali, ia mengubah data dan membiarkan React mengubah halaman.
Vanilla JavaScript
const judul = document.querySelector("#judul");
judul.textContent = "Daftar belanja";
judul.classList.add("sorot");
const daftar = document.querySelector("#daftar");
const item = document.createElement("li");
item.textContent = "teh";
daftar.appendChild(item);
React
function DaftarBelanja() {
const [items, setItems] = React.useState(["kopi"]);
return (
<div>
<h2 className="sorot">Daftar belanja</h2>
<ul>
{items.map((nama) => (
<li key={nama}>{nama}</li>
))}
</ul>
<button onClick={() => setItems([...items, "teh"])}>
Tambah teh
</button>
</div>
);
}
Perbedaan inti bab ini ada di sini. Cara vanilla disebut imperatif, kamu menyuruh halaman langkah demi langkah: pilih elemen, ubah teksnya, tambah anaknya. Cara React disebut deklaratif, kamu mendeskripsikan tampilan dari data yang ada, lalu membiarkan React mengurus DOM saat data berubah. items adalah state, data milik komponen yang bila berubah membuat komponen dirender ulang. Untuk halaman kecil, memerintah DOM secara manual terasa ringan. Untuk halaman besar yang datanya terus berubah, cara manual melelahkan dan rawan lupa, dan di situ React mengambil alih. Bab 14 membahas itu lebih jauh.
Demo Hidup
Demo di bawah memakai semua perintah bab ini pada halaman sungguhan. Satu tombol mengganti teks paragraf lewat textContent. Satu tombol menyalakan dan mematikan class lewat classList.toggle. Satu tombol membuat li baru dengan createElement lalu menempelkannya dengan appendChild. Semuanya jalan tanpa build tool.
Ubah halaman ini langsung. Teks baru mengganti isi paragraf, Sorot menyalakan dan mematikan warna, Tambah item menambah baris daftar.
Paragraf ini bisa diubah oleh kode di atas.
- kopi
Begini cara baca demonya. Setiap tombol dipasang pendengar klik dengan addEventListener, perintah untuk menjalankan fungsi saat suatu kejadian terjadi. Kejadian dibahas penuh di bab 9, di sini cukup tahu tombolnya berfungsi. Tombol Ubah teks membaca isi kotak, memotong spasi di ujungnya dengan trim, lalu mengganti textContent paragraf, dengan satu pengaman: teks kosong diabaikan agar paragraf tidak hilang tanpa sengaja. Tombol Sorot memanggil classList.toggle, menyalakan class saat belum ada dan mematikan saat sudah ada. Tombol Tambah item membuat li baru, memberi nomor dari jumlah anak daftar, lalu menempelkannya di akhir. Coba tekan Sorot dua kali, lalu tambah tiga item.
Ringkasan bab ini. DOM adalah peta objek halaman yang disusun browser dari HTML, dan document adalah pintu masuknya. querySelector memilih satu elemen dengan selektor bergaya CSS, querySelectorAll memilih semuanya. textContent mengganti isi teks, classList mengatur class, createElement dan appendChild menambah elemen baru. Versi vanilla memerintah halaman langkah demi langkah, versi React mendeskripsikan tampilan dari data. Bab berikutnya membahas event, cara halaman bereaksi pada klik dan ketikan.