Keranjang belanja di halaman Budi punya tiga wajah: item biasa, item terpilih, dan item yang melebihi batas pembelian. Cara paling rapi menandai ketiganya bukan mengubah CSS langsung dari JavaScript, melainkan mengatur class pada elemen — dan menyerahkan sepenuhnya ke CSS untuk memutuskan seperti apa tampilan setiap class. Pola ini menjaga JavaScript tetap berurusan dengan struktur dan status, bukan dengan detail gaya.

Chapter ini membahas classList, antarmuka bawaan browser untuk mengatur daftar class sebuah elemen: menambah, membuang, memeriksa, mengganti, dan melakukan dua hal sekaligus dengan satu panggilan toggle. Kita juga melihat properti className beserta satu jebakan yang sering menimpa pemula.

classList: Bukan String Biasa #

Di HTML, class ditulis sebagai satu string: class="kartu aktif". Di JavaScript, browser membungkus string itu menjadi object bertipe DOMTokenList yang bisa diakses lewat properti classList. Object ini berperilaku seperti daftar: punya length, bisa dijajal dengan for...of, dan — yang terpenting — punya method yang tahu bahwa isinya adalah kumpulan class, bukan karakter bebas.

Dengan kata lain, classList menghilangkan pekerjaan kasar yang biasanya timbul kalau kita memanipulasi string sendiri: menambah spasi, memeriksa kata di tengah string, atau menjaga agar tidak ada spasi ganda. Semua itu sudah ditangani method-method berikut.

Satu panduan memilih antara class dan data-* dari chapter sebelumnya: class untuk status yang punya aturan tampilan (aktif, terpilih, dibatasi), dan data-* untuk data yang tidak terkait tampilan (stok, id server). Dengan pemisahan ini, perubahan gaya tidak menyentuh data, dan perubahan data tidak menyentuh gaya.

// kelola-kelas.js — mengatur class tanpa merangkai string

const kartu = document.querySelector("#kartu");

// 1. add: menambah satu atau beberapa class
kartu.classList.add("aktif");
kartu.classList.add("dibatasi", "terpilih");
console.log(kartu.className);                // kartu aktif dibatasi terpilih

// 2. contains: memeriksa keanggotaan
console.log(kartu.classList.contains("aktif"));    // true
console.log(kartu.classList.contains("menempel")); // false

// 3. toggle: saklar dua arah
console.log(kartu.classList.toggle("menempel")); // true (baru ditambah)
console.log(kartu.classList.toggle("menempel")); // false (dilepas)

// 4. replace dan remove
kartu.classList.replace("dibatasi", "bebas");
kartu.classList.remove("terpilih");
console.log(kartu.className);                // kartu aktif bebas

Elemen contohnya sederhana — <div id="kartu" class="kartu"> berisi satu judul produk — sehingga setiap perubahan daftar class mudah dilacak.

Output yang Dihasilkan (console browser):

text
kartu aktif dibatasi terpilih
true
false
true
false
kartu aktif bebas

Keluaran dicatat dari eksekusi nyata di lingkungan jsdom dan identik dengan console browser. Mari kita bedah:

  1. Baris 6–7 (add): panggilan pertama menambah satu class, panggilan kedua membuktikan bahwa add menerima beberapa argumen sekaligus — tiga class kini menempel tanpa satu pun tanda spasi yang kita rangkai manual. Method add tidak menduplikasi: menambah class yang sudah ada tidak mengubah apa pun.
  2. Baris 8 (className sebagai jendela): properti className mengembalikan seluruh daftar sebagai string — kartu aktif dibatasi terpilih. String inilah yang dibaca oleh CSS.
  3. Baris 11–12 (contains): pemeriksaan keanggotaan mengembalikan boolean murni — aktif ada, menempel belum. Inilah pengganti yang aman untuk pola rentan seperti className.includes("aktif"), yang bisa keliru pada nama class serupa (misalnya aktifkan).
  4. Baris 15–16 (toggle dua kali): panggilan pertama menambah menempel karena belum ada, dan mengembalikan true — keadaan class setelah panggilan. Panggilan kedua pada class yang sama justru melepaskannya dan mengembalikan false.
  5. Baris 19–21 (replace dan remove): replace menukar satu class dengan yang lain dalam satu langkah (mengembalikan true bila class lama memang ditemukan), lalu remove membuang terpilih. Daftar akhirnya tersisa kartu aktif bebas.

toggle: Saklar Dua Arah #

toggle adalah kependekan dari pola yang sangat umum: bila class belum ada, tambahkan; bila sudah ada, buang. Tanpa toggle, pola itu ditulis dengan contains plus cabang if — dua baris logika untuk satu niat sederhana.

Nilai kembalian toggle selalu menjawab “apakah class ada setelah panggilan ini”: true berarti kini menempel, false berarti kini dilepas. Bila kita ingin memaksa arah tertentu — misalnya selalu melepas class terpilih tanpa peduli keadaan sebelumnya — argumen kedua bertipe boolean menyediakannya:

js Memaksa arah toggle
kartu.classList.toggle("aktif", false); // dipaksa dilepas
kartu.classList.toggle("aktif", true);  // dipaksa ditambah

Argumen kedua ini sering dipakai bersama ekspresi kondisi: toggle("salah", !valid) menempelkan class salah tepat ketika data tidak valid, dan melepaskannya ketika valid — satu baris untuk perilaku yang biasanya butuh cabang.

replace dan className #

replace(classLama, classBaru) mengganti satu keanggotaan tanpa menyentuh class lain — berguna saat status berganti nama (misalnya dibatasi menjadi bebas) tanpa mengganggu class visual yang tetap. Bandingkan dengan properti className, yang bekerja pada string utuh:

js Penulisan massal lewat className
kartu.className = "kartu utama";
console.log(kartu.className); // kartu utama

Penugasan className mengganti seluruh daftar — apa pun yang melekat sebelumnya ditinggalkan. Perilaku ini tepat untuk reset massal, dan menjadi jebakan bila niat kita hanya menambah satu class: className = "aktif" akan ikut membuang kartu, class dasar elemen.

Karena classList berperilaku seperti daftar, isinya bisa dijajal tanpa memecah string manual:

js Menjajal classList seperti daftar biasa
const kartu = document.querySelector("#kartu");
console.log(kartu.classList.length); // 1 — awalnya hanya "kartu"
kartu.classList.add("aktif", "terpilih");
for (const nama of kartu.classList) {
  console.log(nama);
}

Output yang Dihasilkan (console browser):

text
1
kartu
aktif
terpilih

Perulangan for...of dari section Collections bekerja langsung pada classList, dan Array.from(kartu.classList) mengubahnya menjadi array biasa bila method array dibutuhkan. Ingat pula bahwa classList bersifat live: daftar yang dibaca selalu kondisi terkini elemen tersebut.

Setiap perubahan class langsung terlihat di className, dan CSS yang menargetkan class itu bereaksi tanpa langkah tambahan. Kita sudah bisa memilih elemen, menjelajah, mengganti isi, mengatur atribut, dan menandai status — bagian yang belum bisa kita lakukan adalah membuat elemen yang benar-benar baru. Itulah topik chapter Creating Elements.

Berkas Sumber

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

kelola-kelas.js

Unduh berkas
javascript
// kelola-kelas.js — mengatur class tanpa merangkai string

const kartu = document.querySelector("#kartu");

// 1. add: menambah satu atau beberapa class
kartu.classList.add("aktif");
kartu.classList.add("dibatasi", "terpilih");
console.log(kartu.className);                // kartu aktif dibatasi terpilih

// 2. contains: memeriksa keanggotaan
console.log(kartu.classList.contains("aktif"));    // true
console.log(kartu.classList.contains("menempel")); // false

// 3. toggle: saklar dua arah
console.log(kartu.classList.toggle("menempel")); // true (baru ditambah)
console.log(kartu.classList.toggle("menempel")); // false (dilepas)

// 4. replace dan remove
kartu.classList.replace("dibatasi", "bebas");
kartu.classList.remove("terpilih");
console.log(kartu.className);                // kartu aktif bebas