こんにちは、かつコーチです。
前回は要素の追加・削除を解説しました。
今回は、Webサイトでよく見る「メニューを開閉する」「タブを切り替える」「ボタンを押すと選択状態になる」といった動きの土台になる、クラスの操作方法を扱います。
見た目の変化はCSSで用意しておき、JavaScriptからは「クラスをつけたり外したりするだけ」というのが、実務でも定番の考え方です。
classListとは?
classListの基本
要素のclass属性を操作するためのプロパティが classList です。
<button id="menu-button" class="btn">メニュー</button>
const button = document.querySelector("#menu-button");
console.log(button.classList);
// DOMTokenListというデータ形式で、["btn"] のような中身が確認できる
classList は、その要素についているクラス名の一覧を、専用のメソッドで操作できる形式にしたものです。
配列そのものではありませんが、add ・ remove ・ toggle ・ contains といった、クラス操作に特化した使いやすいメソッドが用意されています。
add・remove・toggleの基本操作
代表的な3つのメソッドを見てみましょう。
const button = document.querySelector("#menu-button");
// クラスを追加する
button.classList.add("is-active");
console.log(button.className);
// "btn is-active"
// クラスを削除する
button.classList.remove("is-active");
console.log(button.className);
// "btn"
// クラスがあれば削除、なければ追加する(反転させる)
button.classList.toggle("is-active");
console.log(button.className);
// "btn is-active"(なかったので追加された)
button.classList.toggle("is-active");
console.log(button.className);
// "btn"(あったので削除された)
特に toggle は、「メニューの開閉」のように、クリックするたびにオン・オフを切り替えたい場面で非常によく使われます。
containsでクラスの有無を判定する
そのクラスがついているかどうかを調べたいときは、contains を使います。
const button = document.querySelector("#menu-button");
button.classList.add("is-active");
if (button.classList.contains("is-active")) {
console.log("メニューは開いています");
} else {
console.log("メニューは閉じています");
}
// メニューは開いています
contains は真偽値(true / false)を返すので、if 文の条件としてそのまま使えます。
className との違い
classNameは文字列をまるごと扱う
classList が登場する前は、className というプロパティを使ってクラスを操作するのが一般的でした。
const button = document.querySelector("#menu-button");
console.log(button.className);
// "btn"
className は、クラス名をまとめて1つの文字列として扱います。
一見シンプルに見えますが、この「文字列として扱う」という性質が、実はつまずきの原因になります。
つまずきポイント:className で1つのクラスだけ消したい
私が実際にハマったのが、複数クラスがついている要素から、特定のクラスだけを外そうとしたときのことです。
❌ Before:className を直接書き換えて他のクラスまで消してしまう
const button = document.querySelector("#menu-button");
// button.className は "btn btn-large is-active" という想定
button.className = "btn-large is-active"; // "btn"だけを外したつもりが…
このコードは一見動いているように見えますが、対象の要素に元々どんなクラスがついているかを毎回正確に把握して、文字列を組み立て直す必要があります。
私は当初、既存のクラス構成を把握しきれずに className を丸ごと上書きしてしまい、意図せず他のクラス(レイアウト用のクラスなど)まで消してしまったことがありました。
見た目が突然崩れて、原因が分からずしばらく悩んだのを覚えています。
✅ After:classListのremoveで対象のクラスだけを安全に外す
const button = document.querySelector("#menu-button");
// button.className は "btn btn-large is-active" という想定
button.classList.remove("btn"); // "btn"だけをピンポイントで削除
console.log(button.className);
// "btn-large is-active"(他のクラスはそのまま残る)
classList.remove() を使えば、指定したクラス名だけをピンポイントで削除できるため、他のクラスに影響を与える心配がありません。
複数のクラス名を扱うときは、className ではなく classList を使うのが基本方針だと覚えておいてください。
classListとCSSを組み合わせた実践例
メニューの開閉をtoggleで実装する
最後に、toggle を使った実践的な例を見てみましょう。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>メニュー開閉サンプル</title>
<style>
.menu {
display: none;
}
.menu.is-open {
display: block;
}
</style>
</head>
<body>
<button id="menu-button">メニュー</button>
<ul class="menu" id="menu">
<li>ホーム</li>
<li>ブログ</li>
<li>お問い合わせ</li>
</ul>
<script>
const button = document.querySelector("#menu-button");
const menu = document.querySelector("#menu");
button.addEventListener("click", function () {
menu.classList.toggle("is-open");
});
</script>
</body>
</html>
ボタンを押すたびに is-open クラスがついたり外れたりし、それに合わせてCSSで定義した見た目(表示・非表示)が切り替わります。
このように、「見た目の切り替え」自体はCSSで用意しておき、JavaScriptはクラスの付け外しだけを担当するという役割分担が、実務でもよく使われる定番の設計です。
JavaScript側で element.style.display = "block" のように直接スタイルを書き換えることもできますが、その方法については次回の記事で詳しく扱います。
まとめ
この記事のポイント
classListはadd・remove・toggle・containsでクラスを安全に操作できるclassNameは文字列全体を扱うため、他のクラスまで意図せず消してしまうリスクがある- 複数クラスを扱う場面では
classNameではなくclassListを使うのが基本 toggleはメニューの開閉など、オン・オフを切り替える動きの定番- 見た目の切り替えはCSSに任せ、JavaScriptはクラスの付け外しに専念すると設計がシンプルになる
次に読むべき記事
クラスの操作ができるようになったら、次はスタイルを直接JavaScriptから操作する方法を見ていきましょう。
→ 次の記事:スタイルをJavaScriptから操作する方法