Chapter sebelumnya menempelkan JavaScript langsung di dalam file HTML. Pendekatan itu sah untuk percobaan kecil, tetapi halaman nyata membawa banyak baris script yang dipakai ulang antarhalaman. Pada chapter ini kita mempelajari elemen script dengan src, membandingkan script inline dengan file eksternal, serta mengenal posisi script dan type="module". Di akhir chapter, kita membuat sepasang file nyata: satu halaman HTML dan satu file .js yang saling terhubung.

Elemen script dengan src #

Hubungan antara dokumen HTML dan file JavaScript dinyatakan dengan elemen script yang membawa atribut src:

html Bentuk dasar script eksternal
<script src="sapa.js"></script>

Atribut src menunjuk lokasi file .js dengan aturan path relatif yang sama seperti href pada link CSS: cukup nama filenya bila satu folder. Satu dokumen boleh memuat beberapa elemen script, dan browser mengunduh setiap file yang dirujuk.

Script Inline atau File Eksternal #

Kode JavaScript dapat hidup di dua tempat: menempel di dalam elemen script, atau terpisah pada file .js yang dirujuk dengan src. Perbandingannya:

AspekScript inlineFile eksternal
Letak kodeDi dalam file HTMLFile .js terpisah
Dipakai ulang antarhalamanTidakYa
Disimpan cacheTidak, menempel pada HTMLYa
PerawatanCampur dengan markupTerpisah dan terkendali

Prinsipnya sama dengan pemisahan CSS pada section HTML dan CSS: satu tanggung jawab, satu tempat — pola yang disebut separation of concerns. Manfaat caching pun berlaku: browser menyimpan file .js yang telah diunduh, sehingga pengunjung yang berpindah halaman tidak mengunduhnya dua kali.

Script inline tetap wajar untuk eksperimen cepat atau interaksi sepele di satu halaman. Begitu script menyentuh lebih dari satu halaman, pindahkan ke file eksternal.

Posisi Script: Akhir Body dan Preview defer #

Script tanpa atribut tambahan dieksekusi tepat saat parser browser tiba di barisnya. Bila script merujuk elemen yang belum terbentuk — dipasang di head sedangkan sasarannya di body — pemilihan menghasilkan null dan script melempar error. Solusi klasiknya terlihat pada chapter lalu: menaruh script di akhir body, ketika seluruh elemen telah terbentuk.

Cara modernnya adalah atribut defer: script tetap boleh di head, tetapi eksekusinya ditunda hingga parsing selesai. Detailnya — termasuk perbandingan dengan async — menjadi topik utuh chapter berikutnya; dua pola aman itulah yang kita pegang di section ini.

type=“module” Singkat #

File JavaScript modern dapat dimuat sebagai module:

html Script dimuat sebagai module
<script type="module" src="app.js"></script>

Module mendukung pernyataan import dan export untuk saling memanggil antar file — materi yang layak ditunggu pada kursus JavaScript. Dua hal penting untuk section ini: module dieksekusi setelah parsing selesai (berperilaku seperti defer), sementara contoh-contoh kita tetap memakai script classic agar fokus pada sisi HTML.

Fallback noscript #

Sebagian kecil pengunjung menonaktifkan JavaScript. Elemen noscript menyediakan konten pengganti untuk kondisi tersebut:

html Pesan pengganti saat JavaScript mati
<noscript>
  <p>Fitur interaktif memerlukan JavaScript. Aktifkan di pengaturan browser.</p>
</noscript>

Browser yang menjalankan JavaScript mengabaikan isi noscript, sehingga pesan hanya tampil bagi yang membutuhkannya.

Contoh Lengkap: Halaman dengan Script Eksternal #

Contoh berikut terdiri atas dua file bundle: halaman-sapa.html dan sapa-menu.js, dipasang di akhir body sesuai pola aman di atas. Dua kemampuan JavaScript yang dipakai — memilih elemen dan mengubah teksnya — baru dibedah pada dua chapter berikutnya; fokus kita adalah bagaimana kedua file terhubung.

<!doctype html>
<html lang="id">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Toko Kelontong Siti</title>
</head>
<body>
  <h1>Toko Kelontong Siti</h1>
  <p id="status">Menyiapkan menu…</p>
  <script src="sapa-menu.js"></script>
</body>
</html>
javascript sapa-menu.js
// Menyapa pengunjung dari file eksternal
const status = document.getElementById("status");

status.textContent = "Halo, Budi! Menu hari ini: soto ayam dan es teh.";

Output yang Dihasilkan:

text
Jendela browser menampilkan:
  - Heading "Toko Kelontong Siti"
  - Paragraf yang berubah dari "Menyiapkan menu…" menjadi
    "Halo, Budi! Menu hari ini: soto ayam dan es teh."

Mari kita telaah peran setiap baris penting di atas:

  1. Baris 9-10 HTML (<h1> dan <p id="status">): konten asli halaman dengan teks sementara sebelum script bekerja.
  2. Baris 11 HTML (<script src="sapa-menu.js">): titik koneksi kedua file; letaknya di akhir body sehingga elemen #status telah ada saat script dieksekusi.
  3. Tag penutup </script>: tetap hadir meski isi script kosong, sesuai peringatan di atas.
  4. Baris 2 JS (document.getElementById("status")): script memilih paragraf sasaran berdasarkan id-nya.
  5. Baris 4 JS (status.textContent = ...): script mengganti teks paragraf; perubahan langsung tampil di layar.

Perhatikan bahwa file JS tidak berisi markup dan file HTML hampir tidak berisi logika. Pertanyaan tersisa: kapan persisnya script itu dieksekusi, dan apa yang terjadi bila posisinya berpindah? Chapter Script dan Defer menjawabnya lewat bedah urutan eksekusi classic, defer, dan async.

Referensi resmi untuk pendalaman:

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

halaman-sapa.html

Unduh berkas
html
<!doctype html>
<html lang="id">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Toko Kelontong Siti</title>
</head>
<body>
  <h1>Toko Kelontong Siti</h1>
  <p id="status">Menyiapkan menu…</p>
  <script src="sapa-menu.js"></script>
</body>
</html>

sapa-menu.js

Unduh berkas
javascript
// Menyapa pengunjung dari file eksternal
const status = document.getElementById("status");

status.textContent = "Halo, Budi! Menu hari ini: soto ayam dan es teh.";