Setelah kita belajar mengambil dan mengubah isi elemen dengan innerHTML dan textContent, sekarang saatnya mengenal event klik (onclick). Event klik adalah event paling umum dalam pengembangan web - hampir semua interaksi pengguna dimulai dengan klik tombol!
Apa Itu Event Klik?
Event adalah aksi yang dilakukan pengguna pada website, seperti klik, hover, ketik, scroll, dll. Event klik (onclick) terjadi ketika pengguna mengklik suatu elemen (biasanya tombol, link, atau gambar). Kita bisa merespon event klik dengan menjalankan fungsi JavaScript.
-
onclick → saat elemen diklik
-
ondblclick → saat elemen di-double klik
-
onmouseover → saat mouse masuk ke elemen
-
onmouseout → saat mouse keluar dari elemen
-
onchange → saat nilai input berubah
-
onsubmit → saat form di-submit
Cara 1: Inline onclick (Atribut Langsung)
Cara paling sederhana: menambahkan atribut onclick langsung di elemen HTML.
Contoh Dasar:
<button onclick="alert('Tombol diklik!')">
Klik Aku
</button>
Memanggil Fungsi yang Sudah Didefinisikan:
<button onclick="sapaPengguna()">Sapa Saya</button>
<script>
function sapaPengguna() {
let nama = prompt("Siapa nama Anda?");
if (nama) {
alert("Halo, " + nama + "! Selamat belajar JavaScript.");
}
}
</script>
- Sederhana dan mudah dipahami pemula
- Cocok untuk testing cepat
- Mencampur HTML dan JavaScript (sulit di-maintenance)
- Tidak bisa menambahkan banyak event listener ke elemen yang sama
- Sulit untuk kode yang kompleks
Cara 2: Menggunakan Properti onclick di JavaScript
Cara ini lebih rapi karena JavaScript dipisah dari HTML. Kita memilih elemen, lalu menambahkan fungsi ke properti onclick-nya.
Contoh:
<button id="myButton">Klik Saya</button>
<p id="hasil"></p>
<script>
// Ambil elemen tombol
const tombol = document.getElementById("myButton");
// Tambahkan fungsi onclick
tombol.onclick = function() {
document.getElementById("hasil").innerHTML = "Tombol telah diklik!";
};
</script>
Contoh dengan Fungsi Terpisah:
<button id="hitungBtn">Hitung Klik</button>
<p>Jumlah klik: <span id="counter">0</span></p>
<script>
let jumlahKlik = 0;
const btn = document.getElementById("hitungBtn");
const counterSpan = document.getElementById("counter");
function tambahKlik() {
jumlahKlik++;
counterSpan.textContent = jumlahKlik;
}
btn.onclick = tambahKlik;
</script>
Jumlah klik: 0
- Pemisahan HTML dan JavaScript (lebih rapi)
- Mudah dipahami
- Hanya bisa menambahkan satu fungsi ke satu event
- Jika ditimpa, fungsi sebelumnya akan hilang
Cara 3: addEventListener (Paling Disarankan)
addEventListener adalah cara paling modern dan fleksibel. Kelebihannya: bisa menambahkan banyak fungsi ke event yang sama, dan lebih mudah dikelola.
Sintaks Dasar:
element.addEventListener("click", function() {
// kode yang dijalankan saat diklik
});
Contoh:
<button id="actionBtn">Aksi</button>
<script>
const btn = document.getElementById("actionBtn");
btn.addEventListener("click", function() {
alert("Pertama: Tombol diklik!");
});
btn.addEventListener("click", function() {
alert("Kedua: Event listener kedua juga berjalan!");
});
</script>
Contoh dengan Fungsi Bernama:
<button id="ubahWarnaBtn">Ubah Warna</button>
<script>
const btn = document.getElementById("ubahWarnaBtn");
function ubahKeBiru() {
document.body.style.backgroundColor = "#3b82f6";
}
function ubahKePutih() {
document.body.style.backgroundColor = "white";
}
btn.addEventListener("click", ubahKeBiru);
btn.addEventListener("dblclick", ubahKePutih);
</script>
Klik sekali untuk ubah background menjadi biru, double klik untuk kembali putih.
- Bisa menambahkan banyak fungsi ke event yang sama
- Bisa menghapus event listener dengan
removeEventListener - Kode lebih terstruktur dan mudah di-maintenance
- Memisahkan HTML dan JavaScript dengan bersih
- Support untuk semua event (bukan hanya onclick)
Perbandingan Tiga Cara Menambahkan Event Klik
| Aspek | Inline onclick | Properti onclick | addEventListener |
|---|---|---|---|
| Pemisahan HTML/JS | Campur aduk | Terpisah | Terpisah |
| Bisa banyak fungsi | Tidak | Tidak (menimpa) | Ya |
| Mudah untuk pemula | Sangat mudah | Mudah | Perlu belajar |
| Rekomendasi | Hanya untuk testing | Website sederhana | Website profesional |
Contoh Proyek: Aplikasi Quiz Interaktif
Berikut contoh aplikasi quiz yang menggunakan event klik untuk navigasi dan menjawab soal:
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>Quiz Interaktif - Event Klik</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.quiz-container {
background: white;
border-radius: 20px;
padding: 30px;
max-width: 600px;
width: 100%;
box-shadow: 0 20px 40px rgba(0,0,0,0.2);
}
h1 {
text-align: center;
color: #1e293b;
margin-bottom: 20px;
}
.question {
font-size: 20px;
font-weight: bold;
margin-bottom: 20px;
padding: 15px;
background: #f0f4f8;
border-radius: 10px;
}
.options {
display: flex;
flex-direction: column;
gap: 12px;
margin-bottom: 25px;
}
.option {
background: #f8fafc;
border: 2px solid #e2e8f0;
border-radius: 10px;
padding: 12px 15px;
cursor: pointer;
transition: all 0.2s;
}
.option:hover {
background: #eef2ff;
border-color: #3b82f6;
}
.option.selected {
background: #3b82f6;
color: white;
border-color: #3b82f6;
}
.nav-buttons {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
}
button {
background: #3b82f6;
color: white;
border: none;
padding: 10px 20px;
border-radius: 8px;
cursor: pointer;
font-size: 14px;
}
button:hover {
background: #2563eb;
}
button:disabled {
background: #94a3b8;
cursor: not-allowed;
}
.result {
text-align: center;
padding: 15px;
border-radius: 10px;
margin-top: 15px;
}
.score-high {
background: #dcfce7;
color: #166534;
}
.score-low {
background: #fee2e2;
color: #991b1b;
}
.info {
background: #eef2ff;
padding: 15px;
border-radius: 10px;
margin-top: 20px;
font-size: 13px;
}
</style>
</head>
<body>
<div class="quiz-container">
<h1>Quiz Pengetahuan Umum</h1>
<div id="questionArea">
<div class="question" id="questionText"></div>
<div class="options" id="optionsContainer"></div>
</div>
<div class="nav-buttons">
<button id="prevBtn" disabled>Sebelumnya</button>
<span id="questionCounter" style="color: #64748b;"></span>
<button id="nextBtn">Selanjutnya</button>
</div>
<button id="submitBtn" style="width: 100%; display: none;">Lihat Hasil</button>
<div id="resultArea" style="display: none;"></div>
<div class="info">
Event yang Digunakan: Setiap opsi jawaban punya event klik untuk memilih jawaban. Tombol navigasi menggunakan event klik untuk berpindah soal. Tombol submit menampilkan hasil akhir.
</div>
</div>
<script>
// Data soal
const questions = [
{
text: "Apa ibu kota Indonesia?",
options: ["Surabaya", "Bandung", "Jakarta", "Medan"],
correct: 2
},
{
text: "Siapa presiden pertama Indonesia?",
options: ["Soeharto", "Soekarno", "BJ Habibie", "Abdurrahman Wahid"],
correct: 1
},
{
text: "Apa bahasa resmi negara Indonesia?",
options: ["Jawa", "Sunda", "Inggris", "Indonesia"],
correct: 3
},
{
text: "Gunung tertinggi di Indonesia adalah?",
options: ["Gunung Merapi", "Gunung Rinjani", "Gunung Semeru", "Puncak Jaya"],
correct: 3
}
];
let currentIndex = 0;
let userAnswers = new Array(questions.length).fill(-1);
// Ambil elemen DOM
const questionText = document.getElementById("questionText");
const optionsContainer = document.getElementById("optionsContainer");
const prevBtn = document.getElementById("prevBtn");
const nextBtn = document.getElementById("nextBtn");
const submitBtn = document.getElementById("submitBtn");
const questionCounter = document.getElementById("questionCounter");
const resultArea = document.getElementById("resultArea");
const questionArea = document.getElementById("questionArea");
function renderQuestion() {
const q = questions[currentIndex];
questionText.textContent = q.text;
questionCounter.textContent = `${currentIndex + 1} / ${questions.length}`;
// Render opsi
let optionsHtml = "";
q.options.forEach((opt, idx) => {
const isSelected = (userAnswers[currentIndex] === idx);
const selectedClass = isSelected ? "selected" : "";
optionsHtml += `
${String.fromCharCode(65 + idx)}. ${opt}
`;
});
optionsContainer.innerHTML = optionsHtml;
// Tambahkan event listener ke setiap opsi
document.querySelectorAll(".option").forEach(opt => {
opt.addEventListener("click", function() {
const selectedIdx = parseInt(this.dataset.optIndex);
userAnswers[currentIndex] = selectedIdx;
renderQuestion(); // re-render untuk update tampilan selected
});
});
// Atur tombol navigasi
prevBtn.disabled = (currentIndex === 0);
if (currentIndex === questions.length - 1) {
nextBtn.style.display = "none";
submitBtn.style.display = "block";
} else {
nextBtn.style.display = "block";
submitBtn.style.display = "none";
}
}
function nextQuestion() {
if (currentIndex < questions.length - 1) {
currentIndex++;
renderQuestion();
}
}
function prevQuestion() {
if (currentIndex > 0) {
currentIndex--;
renderQuestion();
}
}
function showResult() {
let score = 0;
questions.forEach((q, idx) => {
if (userAnswers[idx] === q.correct) {
score++;
}
});
const percentage = (score / questions.length) * 100;
let resultHtml = `
Hasil Quiz
Anda menjawab benar ${score} dari ${questions.length} soal
Nilai: ${percentage}%
`;
// Tampilkan jawaban yang benar untuk soal yang salah
resultHtml += `Rangkuman Jawaban:`;
questions.forEach((q, idx) => {
const isCorrect = (userAnswers[idx] === q.correct);
const status = isCorrect ? "Benar" : "Salah";
const correctAnswer = q.options[q.correct];
resultHtml += `
-
${idx + 1}. ${q.text}
Jawaban Anda: ${userAnswers[idx] !== -1 ? q.options[userAnswers[idx]] : "Tidak dijawab"}
(${status})
${!isCorrect ? `Jawaban benar: ${correctAnswer}` : ""}
`;
});
resultHtml += `
`;
resultArea.innerHTML = resultHtml;
resultArea.style.display = "block";
questionArea.style.display = "none";
prevBtn.style.display = "none";
nextBtn.style.display = "none";
submitBtn.style.display = "none";
questionCounter.style.display = "none";
}
// Event listeners
prevBtn.addEventListener("click", prevQuestion);
nextBtn.addEventListener("click", nextQuestion);
submitBtn.addEventListener("click", showResult);
// Render soal pertama
renderQuestion();
</script>
</body>
</html>
Hasil visual quiz:
Quiz Pengetahuan Umum
Event Lain yang Sering Digunakan
| Event | Kapan Terjadi? | Contoh Penggunaan |
|---|---|---|
dblclick |
Double klik | Mengedit item di daftar |
mouseover |
Mouse masuk ke elemen | Efek hover, tooltip |
mouseout |
Mouse keluar dari elemen | Mengembalikan efek hover |
change |
Nilai input berubah | Validasi form real-time |
keyup |
Tombol keyboard dilepaskan | Search live, filter data |
submit |
Form di-submit | Validasi sebelum kirim data |
Cara Menghapus Event Listener
Kadang kita perlu menghapus event listener yang sudah ditambahkan. Ini berguna untuk menghemat memori atau mencegah eksekusi berulang.
<button id="aktifBtn">Aktifkan Event</button>
<button id="nonaktifBtn">Nonaktifkan Event</button>
<p id="status">Event aktif</p>
<script>
const aktifBtn = document.getElementById("aktifBtn");
const nonaktifBtn = document.getElementById("nonaktifBtn");
const statusP = document.getElementById("status");
function handleClick() {
alert("Tombol diklik!");
}
aktifBtn.addEventListener("click", handleClick);
nonaktifBtn.addEventListener("click", function() {
aktifBtn.removeEventListener("click", handleClick);
statusP.textContent = "Event sudah dinonaktifkan";
statusP.style.color = "red";
});
</script>
Event aktif
Untuk menggunakan
removeEventListener, fungsi yang dihapus harus sama persis (baik isi maupun referensi) dengan fungsi yang ditambahkan. Fungsi anonim (tanpa nama) tidak bisa dihapus.
Bisa dihapus:
btn.addEventListener("click", myFunction);
Tidak bisa dihapus:
btn.addEventListener("click", function() { ... });
Kesalahan Umum Pemula
- Lupa menambahkan tanda kurung pada fungsi →
onclick="myFunction"(salah) vsonclick="myFunction()"(benar). - Mencoba menambahkan event listener ke elemen yang belum dimuat → Letakkan script di akhir
bodyatau gunakanDOMContentLoaded. - Lupa bahwa event listener bisa ditambahkan berkali-kali → Jika tidak hati-hati, event bisa dijalankan berkali-kali (double execution).
- Menggunakan fungsi anonim saat perlu removeEventListener → Fungsi anonim tidak bisa dihapus.
- Typo pada nama event →
onClick(salah, huruf C besar) vsonclick(benar).
- Gunakan
console.log("Event terpanggil")untuk memastikan event berjalan - Cek tab Console di Developer Tools (F12) untuk melihat pesan error
- Pastikan elemen berhasil dipilih:
console.log(element)(jika null, berarti ID salah) - Jika event terpanggil berkali-kali, cek apakah ada multiple event listener yang sama
Latihan Singkat
- Buat file HTML baru dengan judul "Latihan Event Klik"
- Buat 3 tombol dengan inline onclick: masing-masing menampilkan alert berbeda
- Buat 1 tombol dengan properti onclick yang mengubah teks paragraf
- Buat 1 tombol dengan addEventListener yang menambah angka counter setiap diklik
- Buat tombol "Reset" untuk mengatur ulang counter ke 0
- Simpan dan buka di browser, coba semua tombol
Intisari Hari Ini
- Inline onclick → atribut langsung di HTML (mudah tapi campur aduk)
- Properti onclick →
element.onclick = function(lebih rapi, tapi hanya satu fungsi) - addEventListener →
element.addEventListener("click", function)(paling disarankan, bisa banyak fungsi) - Gunakan
addEventListeneruntuk website profesional - Event bisa dihapus dengan
removeEventListener(fungsi harus sama persis) - Letakkan script di akhir
bodyagar elemen sudah dimuat
- Buat grid kartu 4x4 (total 8 pasang kartu)
- Setiap kartu memiliki sisi depan (angka/gambar) dan sisi belakang (tanda tanya)
- Klik kartu untuk membukanya (event klik)
- Jika dua kartu yang dibuka memiliki nilai yang sama, kartu tetap terbuka (match)
- Jika tidak sama, kartu akan tertutup kembali setelah 1 detik
- Hitung jumlah percobaan (moves)
- Tampilkan pesan "Selamat! Anda menang!" saat semua kartu terbuka
- Tombol "Reset Game" untuk memulai ulang permainan
- Gunakan
addEventListeneruntuk semua event klik - Gunakan CSS Grid untuk layout kartu dan styling yang menarik
Bonus: Tambahkan timer (hitungan mundur atau maju) dan efek animasi saat kartu dibuka.
Selamat mencoba!
Artikel Sebelumnya: HTML Dasar #28 - Mengambil dan Mengubah Isi Elemen HTML (innerHTML, textContent)
Artikel Selanjutnya: HTML Dasar #30 - Menampilkan/Menyembunyikan Elemen dengan JavaScript
