classList.toggle
classlist.toggle
一言で言うと
DOM 要素の class 属性を「あれば外す、なければ付ける」と 1 行で切り替えるブラウザ標準 API。第 2 引数で強制 ON / OFF も指定できる。
もう少し詳しく
一言で言うと
DOM 要素の class 属性を「あれば外す、なければ付ける」と 1 行で切り替えるブラウザ標準 API。第 2 引数で強制 ON / OFF も指定できる。
詳細
element.classList は DOMTokenList という class 名専用の API で、add / remove / contains / toggle / replace を持ちます。中でも toggle は現在の状態を見て自動で反転してくれるので、ハンバーガーメニューの開閉、ダークモード切替、アクティブタブ表示などで毎回登場します。
第 2 引数 force (省略可) を渡すと、強制的に付ける / 外す動作になります。条件式の結果をそのまま渡せばよく、if (cond) add else remove を 1 行に圧縮できます。
戻り値は クラスが付いた状態なら true、外れた状態なら false で、次の処理 (aria 属性更新など) に分岐させやすいです。
具体例
const btn = document.querySelector("#menu-btn")!;
const nav = document.querySelector("#nav")!;// 1. 基本: 押すたびに開閉
btn.addEventListener("click", () => {
const isOpen = nav.classList.toggle("open");
btn.setAttribute("aria-expanded", String(isOpen));
});
// 2. 第 2 引数で強制
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
document.documentElement.classList.toggle("dark", prefersDark);
// prefersDark が true なら "dark" を付ける、false なら外す
// 3. 複数クラスは一度に渡せない (1 つずつ)
nav.classList.add("open", "animated"); // add は複数 OK
// nav.classList.toggle("open", "animated"); // ❌ 第 2 引数は force
モダンブラウザはすべてサポート済みでポリフィル不要です。なお IE11 は基本的な toggle 機能のみ対応しており、第 2 引数 force は未サポートです。
使い分け / トレードオフ
addClass / removeClass (jQuery 系) との比較 — jQuery を捨てて素の DOM API に戻る流れの中で、classList は jQuery と同等以上の API を提供します。Vanilla JS なら classList を使うのが正解で、jQuery を残す積極的な理由はもうほとんどありません。
React / Vue では使わない — React の className や Vue の :class を使うほうが宣言的で再描画と整合します。useState の boolean を class に bind するのが定番パターンです。直接 classList.toggle を呼ぶと React の仮想 DOM とずれて不具合の原因になります。
第 2 引数 force は省略時のみ「現在の状態を反転」で、true / false を渡したときは状態を見ずに上書きします。フラグ駆動なら必ず force を渡すほうが安全です。