Proyek Mini: Aplikasi Kuis Interaktif
Proyek penutup: rancang dan bangun aplikasi kuis lengkap dari nol, layar mulai, timer per soal, skor akhir, dan highscore tersimpan di localStorage.
Misi Proyek
Kamu akan membangun aplikasi kuis pilihan ganda yang lengkap dan bisa dipakai sungguhan: ada layar mulai, soal muncul satu per satu dengan timer, jawaban langsung dinilai, skor akhir ditampilkan, dan skor tertinggi tersimpan permanen di browser. Ini proyek integrasi: hampir semua yang kamu pelajari (array, object, DOM, event, timer, localStorage) dipakai bersama dalam satu aplikasi nyata.
Arsitektur: Pecah Masalahnya Dulu
Jangan langsung menulis kode. Aplikasi kuis punya 4 bagian yang bisa dipikirkan terpisah:
1. Struktur data soal. Satu array of object, tiap object punya pertanyaan, daftar pilihan, dan index jawaban benar. Contoh bentuknya:
const soal = [
{
pertanyaan: "Ibukota Indonesia?",
pilihan: ["Jakarta", "Bandung", "Surabaya", "Medan"],
jawaban: 0 // index jawaban benar
},
// tambah minimal 4 soal lagi
];Memisahkan DATA dari LOGIKA adalah keputusan arsitektur terpenting: menambah soal baru tinggal menambah object, tanpa menyentuh kode sama sekali.
2. State aplikasi. Variabel-variabel yang melacak "posisi" permainan: index soal saat ini, skor, sisa waktu timer, dan apakah kuis sedang berjalan. Semua fungsi membaca dan mengubah state yang sama ini.
3. Fungsi render. Satu fungsi untuk tiap layar: tampilMulai() (judul + tombol mulai + highscore), tampilSoal() (pertanyaan + tombol pilihan + timer), tampilHasil() (skor akhir + tombol main lagi). Tiap fungsi mengosongkan container lalu mengisi ulang dengan DOM yang dibuat via JavaScript.
4. Fungsi logika. mulaiKuis() (reset state, tampilkan soal pertama), cekJawaban(indexDipilih) (bandingkan dengan kunci, tambah skor, beri umpan balik visual), soalBerikut() (lanjut atau ke layar hasil), dan simpanHighscore() (bandingkan dengan localStorage).
Alur Timer Per Soal
Timer adalah bagian tersulit, jadi rancang dengan hati-hati. Setiap soal diberi waktu misalnya 15 detik memakai setInterval yang mengurangi sisa waktu tiap detik dan mengupdate tampilan. Dua hal WAJIB diingat: pertama, hentikan interval lama (clearInterval) setiap pindah soal, kalau tidak timer bertumpuk dan berjalan makin cepat. Kedua, saat waktu habis, perlakukan seperti jawaban salah lalu otomatis lanjut ke soal berikutnya.
Menyimpan Highscore
localStorage hanya menyimpan string, jadi bungkus angka dengan JSON.stringify saat menyimpan dan JSON.parse (atau Number) saat membaca. Polanya: saat kuis selesai, baca highscore lama (default 0 jika belum ada), bandingkan dengan skor baru, simpan yang lebih besar, lalu tampilkan keduanya di layar hasil ("Skor: 80, Tertinggi: 100").
Umpan Balik Visual
Aplikasi terasa "hidup" kalau merespons: pilihan yang diklik benar berubah hijau, yang salah berubah merah, tombol pilihan di-disable setelah menjawab agar tidak bisa klik dua kali, dan ada jeda singkat sebelum soal berikutnya muncul. Detail-detail kecil ini yang membedakan aplikasi jadi-jadian dengan aplikasi sungguhan.
Jebakan Umum Proyek Ini
Pertama, timer bertumpuk (lupa clearInterval) adalah bug nomor satu di proyek seperti ini. Kedua, menempel event listener ke tombol yang di-render ulang tanpa membersihkan yang lama bisa membuat satu klik terhitung berkali-kali: render ulang container dengan innerHTML = "" sebelum mengisi, atau pakai event delegation. Ketiga, jangan campur data dan tampilan: fungsi cek jawaban tidak boleh membaca teks dari tombol (rentan berubah), ia harus membaca dari array soal memakai index. Keempat, uji alur lengkapnya: mulai, jawab benar, jawab salah, biarkan waktu habis, main lagi, dan refresh browser untuk memastikan highscore bertahan.
Catatan teknis: Arsitektur "state + render + event" yang kamu pakai di sini adalah versi mini dari cara kerja React dan framework modern: state berubah, UI di-render ulang mengikuti state. Memahami pola ini secara manual membuat framework terasa seperti alat bantu, bukan sulap. Setelah proyek ini selesai, kamu siap menggabungkan modul-modul lain: tambah debounce di layar mulai untuk pencarian soal, atau simpan riwayat kuis sebagai array di localStorage.
Tantangan
Pemanasan: Render Satu Soal
Sebelum membangun aplikasi kuis penuh, kamu perlu menguasai fondasinya: menampilkan satu soal dan menilai jawabannya. Ini pemanasan wajib sebelum mengerjakan tugas proyek di bawah. Buat array soal berisi 1 object (pertanyaan + 4 pilihan + index jawaban), render ke halaman sebagai tombol-tombol pilihan, dan saat tombol diklik tampilkan 'Benar!' atau 'Salah!' sesuai kunci jawaban.
<!doctype html> <html> <head> <meta charset="utf-8" /> </head> <body> <h1>Halo JS</h1> <p>Buka console preview untuk melihat output.</p> <script src="index.js"></script> </body> </html>
Tugas
Aplikasi Kuis Interaktif
Bangun aplikasi kuis pilihan ganda LENGKAP dari nol di editor bawah (tanpa playground, tulis semuanya sendiri). Spesifikasi wajib: (1) array soal berisi minimal 5 object dengan bentuk { pertanyaan, pilihan (4 opsi), jawaban (index benar) }; (2) layar mulai dengan judul, tombol mulai, dan tampilan highscore; (3) soal tampil satu per satu dengan TIMER 15 detik per soal, waktu habis dihitung salah dan otomatis lanjut; (4) jawaban langsung dinilai dengan umpan balik visual (benar = hijau, salah = merah); (5) layar hasil menampilkan skor akhir dan tombol main lagi; (6) highscore (skor tertinggi) disimpan di localStorage dan bertahan setelah refresh. Ikuti panduan arsitektur di materi: pisahkan data soal, state, fungsi render, dan fungsi logika.
Kriteria penilaian:
- Minimal 5 soal dengan struktur data yang benar (pertanyaan, 4 pilihan, index jawaban)
- Timer 15 detik per soal berfungsi: waktu habis dihitung salah dan lanjut otomatis tanpa timer bertumpuk
- Ada layar mulai, layar soal, dan layar hasil dengan skor akhir + tombol main lagi
- Highscore tersimpan di localStorage dan bertahan setelah halaman di-refresh
AI tutor akan memeriksa bug, kesalahan syntax, dan memberi saran perbaikan.
Kuis Bab
Uji pemahamanmu: OOP & Topik Lanjutan
Jawab 5 soal berikut, lalu tekan "Periksa Jawaban".
1.Apa keunggulan generator function (function*) dengan yield?
2.Apa syarat mutlak agar fungsi rekursif tidak menyebabkan stack overflow?
3.Kapan throttle lebih tepat daripada debounce untuk event scroll?
4.Apa manfaat utama strict mode ('use strict')?
5.Apa yang bisa dilakukan Proxy?