⚡ Phase 3 — JS
P20 · Pertemuan 20 dari 20
Event, Interaksi & Final Project
Menguasai event listener, manipulasi style via JS, localStorage, form validation, dan membangun website portofolio interaktif sebagai Final Project.
Tujuan Pembelajaran
- 01Menggunakan event listener: click, input, change, submit, keydown
- 02Menguasai addEventListener dan removeEventListener
- 03Memanipulasi style via JS: element.style, classList.add/remove/toggle
- 04Membuat form validation dengan JavaScript
- 05Menggunakan localStorage: setItem, getItem, removeItem
- 06FINAL PROJECT: Website Portofolio Interaktif
Sub-topik & Materi
- 01Event listener: addEventListener("event", callback)
- 02Event types: click, input, change, submit, keydown, keyup, mouseover
- 03classList: .add(), .remove(), .toggle(), .contains()
- 04element.style untuk mengubah inline style via JS
- 05Form validation: cek panjang input, format email, field kosong
- 06localStorage: simpan data di browser (string only, JSON.stringify/parse)
Penjelasan Konsep
Konsep 1
Event Listener — addEventListener
addEventListener(event, callback) adalah cara menambahkan interaktivitas ke elemen. Event yang paling umum: "click" (klik tombol/elemen), "input" (setiap perubahan di input), "change" (nilai berubah dan blur), "submit" (form dikirim), "keydown" (tombol keyboard ditekan). Selalu gunakan e.preventDefault() di form submit agar halaman tidak reload.
javascript
"t-kw">const tombol = document.querySelector("t-st">'#tombol'); "t-kw">const input = document.querySelector("t-st">'#nama'); "t-kw">const form = document.querySelector("t-st">'form'); "t-kw">class="t-cm">// Klik tombol.addEventListener("t-st">'click', () => { console.log("t-st">'Tombol diklik!'); }); "t-kw">class="t-cm">// Input: real-time input.addEventListener("t-st">'input', (e) => { console.log("t-st">'Nilai:', e.target.value); }); "t-kw">class="t-cm">// Form submit form.addEventListener("t-st">'submit', (e) => { e.preventDefault(); "t-kw">class="t-cm">// cegah reload halaman! "t-kw">const nama = input.value.trim(); "t-kw">if (nama === "t-st">'') { alert("t-st">'Nama tidak boleh kosong!'); "t-kw">return; } console.log("t-st">`Halo, ${nama}!`); });
Konsep 2
localStorage — Simpan Data di Browser
localStorage menyimpan data di browser yang tetap ada meski halaman ditutup/refresh. Hanya bisa menyimpan STRING. Untuk menyimpan array/object, gunakan JSON.stringify() saat menyimpan dan JSON.parse() saat membaca. Maksimal sekitar 5MB per origin.
javascript
"t-kw">class="t-cm">// Simpan data localStorage.setItem("t-st">'nama', "t-st">'Ahmad'); localStorage.setItem("t-st">'skor', "t-st">'95'); "t-kw">class="t-cm">// Simpan object/array "t-kw">const data = { nama: "t-st">'Ahmad', kota: "t-st">'Kediri', nilai: [80, 90, 85] }; localStorage.setItem("t-st">'siswa', JSON.stringify(data)); "t-kw">class="t-cm">// Baca data "t-kw">const nama = localStorage.getItem("t-st">'nama'); "t-kw">class="t-cm">// "Ahmad" "t-kw">const skor = Number(localStorage.getItem("t-st">'skor')); "t-kw">class="t-cm">// 95 "t-kw">const siswa = JSON.parse(localStorage.getItem("t-st">'siswa')); "t-kw">class="t-cm">// object "t-kw">class="t-cm">// Hapus localStorage.removeItem("t-st">'nama'); localStorage.clear(); "t-kw">class="t-cm">// hapus semua
Konsep 3
Fetch API — Ambil Data dari Internet
fetch() mengambil data dari URL (API) secara asynchronous. Gunakan async/await untuk kode yang lebih mudah dibaca. Selalu tambahkan try-catch untuk handle error. API publik yang bisa dipakai untuk latihan: JSONPlaceholder, Open Trivia DB, REST Countries.
javascript
"t-kw">class="t-cm">// Fetch dengan "t-kw">async/"t-kw">await + error handling "t-kw">async "t-kw">function ambilData() { try { "t-kw">const response = "t-kw">await fetch("t-st">'https:"t-kw">class="t-cm">//jsonplaceholder.typicode.com/users'); "t-kw">if (!response.ok) { throw "t-kw">new Error("t-st">`Error: ${response.status}`); } "t-kw">const data = "t-kw">await response.json(); tampilkanData(data); } catch (error) { console.error("t-st">'Gagal fetch:', error.message); document.getElementById("t-st">'container').innerHTML = "t-st">'<p "t-kw">class="error">Gagal memuat data. Coba lagi.</p>'; } } "t-kw">function tampilkanData(users) { "t-kw">const container = document.getElementById("t-st">'container'); container.innerHTML = users.map(user => "t-st">` <div "t-kw">class="kartu"> <h2>${user.name}</h2> <p>${user.email}</p> </div> `).join("t-st">''); } ambilData();
Contoh Kode Lengkap
javascript
"t-kw">class="t-cm">// === Event Listener === "t-kw">const tombol = document.getElementById("t-st">'btn-dark'); tombol.addEventListener("t-st">'click', () => { document.body.classList.toggle("t-st">'dark-mode'); "t-kw">const isDark = document.body.classList.contains("t-st">'dark-mode'); localStorage.setItem("t-st">'darkMode', isDark); tombol.textContent = isDark ? "t-st">'☀️ Light' : "t-st">'🌙 Dark'; }); "t-kw">class="t-cm">// Load preferensi dark mode saat halaman dibuka window.addEventListener("t-st">'load', () => { "t-kw">if (localStorage.getItem("t-st">'darkMode') === "t-st">'true') { document.body.classList.add("t-st">'dark-mode'); } }); "t-kw">class="t-cm">// === Form Validation === "t-kw">const form = document.querySelector("t-st">'form'); form.addEventListener("t-st">'submit', (e) => { e.preventDefault(); "t-kw">class="t-cm">// Cegah reload halaman "t-kw">const nama = document.getElementById("t-st">'nama').value.trim(); "t-kw">const email = document.getElementById("t-st">'email').value.trim(); "t-kw">if (!nama) { alert("t-st">'Nama tidak boleh kosong!'); "t-kw">return; } "t-kw">if (!email.includes("t-st">'@')) { alert("t-st">'Format email tidak valid!'); "t-kw">return; } console.log("t-st">'Form berhasil dikirim:', { nama, email }); });
Latihan Kelas · Buat dark mode toggle dan form validation untuk halaman portofolio
1
Tambahkan tombol dark mode toggle di navbar halaman
2
addEventListener click untuk toggle class "dark-mode" di body
3
Simpan preferensi dark mode ke localStorage
4
Load preferensi dari localStorage saat halaman dibuka (window load)
5
Buat form contact dengan validasi: nama tidak kosong, email valid
Kesalahan yang Sering Dibuat
Lupa e.preventDefault() di form submit — halaman reload dan semua input hilang
Fetch tanpa try-catch — jika internet mati atau API error, program crash tanpa pesan yang jelas
Lupa await sebelum fetch() atau .json() — mendapat Promise bukan data aktual
localStorage menyimpan object langsung tanpa JSON.stringify() — tersimpan sebagai "[object Object]"
Memanggil event listener berkali-kali (misal di dalam loop) — handler terpasang ganda