- Bab 3 dari 7
- 30 menit
- 1 latihan kode
- 4 soal kuis
HTML ke JavaScript: Tag Script dan DOM
Di bab ini (9 bagian)
Tujuan bab ini
- Memasang JavaScript ke HTML dengan
<script>inline maupunsrc, di posisi yang aman. - Membedakan script biasa,
defer,async, dantype="module". - Memahami DOM sebagai pohon objek yang diubah JavaScript.
- Memilih elemen, mengubah teks dan atribut, serta membuat dan menyisipkan elemen baru.
Tag <script>: dua bentuk
Seperti CSS, JavaScript bisa ditulis langsung di HTML atau di file terpisah.
Untuk proyek sungguhan, pilih external dengan alasan yang sama seperti CSS: bisa dipakai banyak halaman, di-cache browser, dan HTML tetap bersih. Dua aturan kecil yang sering bikin bingung:
- Tag
<script>wajib ditutup dengan</script>, walau isinya kosong.<script src="..." />tidak dikenali sebagai tag tertutup. - Kalau tag punya
src, kode yang ditulis di antara tag pembuka dan penutup diabaikan. Pilih salah satu.
Path di src mengikuti aturan yang sama dengan href di <link>: relatif terhadap file HTML yang membuka.
Posisi pemuatan: kenapa bisa null
Browser membaca HTML dari atas ke bawah sambil membangun halaman. Saat bertemu <script> biasa (tanpa atribut tambahan), browser berhenti, mengunduh, menjalankan script itu, baru lanjut membaca HTML. Ini disebut parser-blocking.
Akibatnya terlihat di contoh ini:
Console mencetak null, karena saat script berjalan, <h1> belum dibuat. Baris berikutnya seperti judul.textContent = "..." langsung error: Cannot set properties of null. Kodemu benar, waktunya yang salah.
Ada beberapa cara memperbaikinya:
| Cara | Kapan dijalankan | Cocok untuk |
|---|---|---|
<script src> sebelum </body> | Setelah semua elemen di atasnya terbentuk | Cara paling sederhana |
<script defer src> di <head> | Diunduh paralel, dijalankan setelah HTML selesai dibaca, sesuai urutan | Pilihan terbaik untuk kebanyakan script |
<script async src> | Dijalankan begitu selesai diunduh, urutan tidak dijamin | Script mandiri seperti analitik |
<script type="module" src> | Otomatis berperilaku seperti defer | Kode modern yang memakai import/export |
Penjelasan lebih detail:
defermembuat browser mengunduh file sambil terus membaca HTML. Script baru dijalankan setelah seluruh dokumen selesai di-parse, tepat sebelum eventDOMContentLoaded. Kalau ada beberapa scriptdefer, urutannya dijaga sesuai urutan di HTML. Atributdeferhanya berlaku untuk script dengansrc. Di script inline,deferdiabaikan.asyncjuga mengunduh paralel, tapi menjalankan script begitu filenya siap, bisa sebelum HTML selesai, dan urutan antar scriptasynctidak dijamin. Jangan pakai untuk script yang memanipulasi elemen atau yang bergantung pada script lain.type="module"menandai file sebagai ES module (standar sejak ES2015). Module otomatis ditunda sepertidefer, berjalan dalam strict mode, dan variabel tingkat atasnya tidak menjadi global. Module juga bisa memakaiimportuntuk memecah kode ke beberapa file. Detail sintaks modul ada di kelas JavaScript.
Alternatif lain, kode dibungkus dengan event:
Walau script ini ditaruh di <head>, isinya baru jalan setelah struktur halaman siap, jadi judul berubah jadi "Siap!".
DOM: halaman berubah jadi pohon objek
Saat membaca HTML, browser tidak menyimpannya sebagai teks. Ia membangun DOM (Document Object Model): pohon objek di memori. Paling atas ada document, di bawahnya <html>, lalu cabang <head> dan <body>, dan seterusnya sampai teks terkecil.
Poin yang sering disalahpahami: JavaScript tidak mengedit file .html. JavaScript mengedit pohon di memori. Kalau kamu muat ulang halaman, pohon dibangun ulang dari file asli, dan semua perubahan dari JavaScript hilang. Karena itu, di DevTools tab Elements kamu melihat DOM yang sekarang (sudah diubah JS), sedangkan View Page Source menampilkan file asli dari server.
Setiap node di pohon itu adalah objek dengan properti (textContent, id, className) dan method (append, remove, addEventListener).
Memilih elemen
Polanya selalu sama: pilih, simpan ke variabel, lalu ubah.
| Method | Hasil | Kalau tidak ketemu |
|---|---|---|
getElementById("x") | Satu elemen dengan id="x" | null |
querySelector(selector) | Elemen pertama yang cocok dengan selector CSS | null |
querySelectorAll(selector) | Semua yang cocok, berupa NodeList | NodeList kosong |
Kabar baiknya, querySelector memakai selector yang sama persis dengan CSS: #id, .class, [data-status="habis"], nav a. Ilmu selector dari bab sebelumnya langsung terpakai. NodeList dari querySelectorAll bisa di-loop dengan forEach atau for...of.
Mengubah teks dan atribut
textContentmemperlakukan isinya sebagai teks biasa. Kalau isinya<b>, yang tampil adalah tulisan<b>, bukan huruf tebal. Ini pilihan paling aman, terutama untuk input pengguna.innerHTMLmenafsirkan isinya sebagai HTML. Berguna, tapi jangan pernah diisi teks dari pengguna, karena bisa disisipi script jahat (serangan XSS).setAttribute(nama, nilai)mengubah atribut apa pun. Banyak atribut juga punya properti langsung sepertiel.id,el.href,img.src.
Membuat dan menyisipkan elemen
Hasilnya: daftar #daftar mendapat item baru "Belajar DOM" di posisi paling bawah, dengan atribut data-id="4". Elemen dari createElement belum tampil sampai disisipkan ke pohon lewat append (atau appendChild, prepend, before, after). Untuk menghapus elemen, panggil el.remove().
Kesalahan umum
- Script di
<head>tanpadefer, lalu heranquerySelectormenghasilkannull. - Menulis
getElementById("#judul"). Method ini menerima id tanpa#. Sebaliknya,querySelectorbutuh#. - Mengira
querySelectormengembalikan semua elemen. Ia hanya mengambil yang pertama. PakaiquerySelectorAlllalu loop. - Memakai
asyncuntuk script yang mengubah DOM, sehingga kadang jalan kadang error tergantung kecepatan unduhan. - Mengisi
innerHTMLdengan input pengguna. PakaitextContent. - Lupa
appendsetelahcreateElement, jadi elemen baru tidak pernah muncul.
Rangkuman
<script>bisa inline atausrc. Kalau adasrc, isi di dalam tag diabaikan.- Script biasa memblokir parsing. Taruh sebelum
</body>, atau pakaideferdi<head>.asyncuntuk script mandiri,type="module"otomatis tertunda. - DOM adalah pohon objek di memori. JavaScript mengubah pohon itu, bukan file HTML.
- Pilih elemen dengan
getElementById,querySelector, atauquerySelectorAll, yang memakai selector CSS. - Ubah isi dengan
textContent(aman) atauinnerHTML(hati-hati), atribut dengansetAttribute, lalu buat elemen baru dengancreateElementdanappend.
Slide 13 sampai 15 dari deck HTML CSS JavaScript. Penjelasan lengkapnya ada di Bacaan.

Selesaikan bab ini
- 1. Baca materi
- 2. Latihan kode (1)
- 3. Kuis (4 soal)
Latihan kode: Isi daftar materi lewat DOM
HTML-nya punya daftar kosong. Lengkapi JavaScript supaya daftar terisi dari array materi:
- Pilih
#daftardan#jumlah, simpan ke variabel. - Hapus
li.kosongdenganremove(). - Untuk setiap materi, buat
<li>dengancreateElement, isitextContent, beridata-idmulai dari"1", laluappendke daftar. - Ubah teks
#jumlahjadi"3 materi"memakaimateri.length. - Ubah
hrefmilik#sumberjadihttps://developer.mozilla.orgdengansetAttribute.
Cek pemahaman
1Apa yang dicetak `console.log`?
<head> <script> const judul = document.querySelector("#judul"); console.log(judul); </script> </head> <body> <h1 id="judul">Halo</h1> </body>2Atribut apa yang membuat script diunduh paralel lalu dijalankan setelah HTML selesai di-parse, dengan urutan antar script tetap terjaga?
3Kalau tag `<script>` punya atribut `src`, kode yang ditulis di antara tag pembuka dan penutupnya diabaikan.
4Item apa saja yang tampil di daftar setelah script berjalan?
<ul id="daftar"> <li>A</li> <li>B</li> </ul> <script> const li = document.createElement("li"); li.textContent = "C"; document.querySelector("#daftar").append(li); document.querySelector("li").remove(); </script>