JavaScript | DOM 操作:CSS / クラス操作 – classList.toggle

JavaScript
スポンサーリンク

classList.toggle とは何か

classList.toggle は、要素に指定した「CSS クラス」を付けたり外したりするメソッドです。クラスが付いていなければ追加、付いていれば削除します。ここが重要です:第二引数に真偽値を渡すと「常に付ける/常に外す」を明示でき、状態管理が一気に読みやすく、意図通りになります。


基本の使い方(トグルと条件付きトグル)

付いていれば外す、なければ付ける(デフォルト動作)

<button id="btn" class="btn">切り替え</button>
<script>
  const btn = document.getElementById("btn");
  btn.addEventListener("click", () => {
    btn.classList.toggle("is-active"); // 付いていれば外す、なければ付ける
  });
</script>
HTML

ここが重要です:UI の「オン/オフ」操作はこれだけで書けます。複雑な if 文は不要です。

第二引数で「常に付ける/外す」を明示

<div id="panel" class="panel is-hidden"></div>
<button id="open">開く</button>
<button id="close">閉じる</button>
<script>
  const panel = document.getElementById("panel");
  document.getElementById("open").addEventListener("click", () => {
    panel.classList.toggle("is-hidden", false); // 常に外す → 表示
  });
  document.getElementById("close").addEventListener("click", () => {
    panel.classList.toggle("is-hidden", true);  // 常に付ける → 非表示
  });
</script>
HTML

ここが重要です:第二引数は「目標の状態」を表します。true なら付ける、false なら外す。分岐の重複が消え、ミスが減ります。


className や add/remove との使い分け(短く、安全に)

add/remove を一本化できる

function setActive(el, on) {
  el.classList.toggle("is-active", !!on);
}
// setActive(el, true) で add、false で remove
JavaScript

ここが重要です:同じクラスに対して add/remove を書き分けるより、toggle(, 条件) を一箇所で使うと読みやすく、再利用しやすいです。

className より安全で明確

className は“文字列まるごと”の上書きで、スペースや部分一致の罠があります。toggle は「クラス名の完全一致」を安全に扱い、既存のクラスを壊しません。ここが重要です:部分操作は常に classList 系(add/remove/toggle)が基本。


よく使う UI パターン(開閉、選択、モード切替)

ドロワーの開閉(テキストも連動)

<button id="toggle">開く</button>
<aside id="drawer" class="drawer is-hidden">内容</aside>
<script>
  const toggle = document.getElementById("toggle");
  const drawer = document.getElementById("drawer");
  toggle.addEventListener("click", () => {
    const hidden = drawer.classList.toggle("is-hidden");
    toggle.textContent = hidden ? "開く" : "閉じる";
  });
</script>
HTML

ここが重要です:toggle の返り値は「現在の付与状態」(true=付いた、false=外れた)。これを使うと UI 文言を直感的に同期できます。

タブの選択(現在だけ active)

<ul id="tabs">
  <li class="tab is-active">A</li>
  <li class="tab">B</li>
  <li class="tab">C</li>
</ul>
<script>
  const tabs = document.getElementById("tabs");
  tabs.addEventListener("click", (e) => {
    const t = e.target;
    if (!(t instanceof Element)) return;
    const li = t.closest(".tab");
    if (!li) return;

    tabs.querySelectorAll(".tab.is-active")
        .forEach(el => el.classList.toggle("is-active", false)); // 一括で外す
    li.classList.toggle("is-active", true); // 現在だけ付ける
  });
</script>
HTML

ここが重要です:排他的な状態は「全解除 → 現在だけ付与」で事故が減ります。

ダークモードの切替(状態フラグで制御)

<button id="mode">モード切替</button>
<body class="theme-light"></body>
<script>
  const btn = document.getElementById("mode");
  btn.addEventListener("click", () => {
    const darkNow = document.body.classList.toggle("theme-dark");
    document.body.classList.toggle("theme-light", !darkNow);
  });
</script>
HTML

ここが重要です:互いに排他的なクラスは、片方をトグルし、もう片方を反対値で同期すると常に整います。


命名と設計の深掘り(トグルと相性の良いクラス設計)

is-* を“状態”に限定する

is-active、is-open、is-hidden などの状態クラスは、toggle と相性が最高です。JS は is-* クラスだけを触り、見た目のテーマ(theme-)やタイプ(type-)は別管理にします。ここが重要です:役割を分けると、コードの意図が明確になり、衝突が減ります。

返り値を活用して副作用をまとめる

toggle の返り値(付与後の真偽)で、テキストや aria 属性を一緒に更新します。

const open = panel.classList.toggle("is-open");
button.textContent = open ? "閉じる" : "開く";
button.setAttribute("aria-expanded", String(open));
JavaScript

ここが重要です:状態の単一情報源(is-*)から、表示とアクセシビリティを同期すると設計が綺麗です。


よくある落とし穴と回避策(存在・タイミング・排他)

要素存在と実行タイミング

const el = document.querySelector("#target");
if (!el) return; // null ガード
// DOMContentLoaded 以降、または defer スクリプトで実行
JavaScript

ここが重要です:DOM がまだ無いと失敗します。存在チェックと実行タイミングを守るのが基本。

相反するクラスの混在

is-hidden と is-open のような“同時に真にしない”クラスが混在すると表示が破綻します。ここが重要です:相反する組はトグル結果で必ず同期(片方を反転値で付け外し)します。

typo と曖昧な名前

toggle は「完全一致」だけが対象。誤字や似た名前(active/activated)を混ぜると効きません。定数で管理するとミスが減ります。

const ACTIVE = "is-active";
el.classList.toggle(ACTIVE, true);
JavaScript

実践例:通知バナーの種類と表示状態を切り替える

<div id="toast" class="toast type-info is-hidden">保存しました</div>
<button id="ok">成功</button>
<button id="ng">失敗</button>
<script>
  const toast = document.getElementById("toast");
  const ok = document.getElementById("ok");
  const ng = document.getElementById("ng");

  function show(type) {
    // 種類を整理(排他的クラスを掃除)
    toast.classList.toggle("type-info", type === "info");
    toast.classList.toggle("type-success", type === "success");
    toast.classList.toggle("type-error", type === "error");
    // 表示にする
    toast.classList.toggle("is-hidden", false);
  }
  ok.addEventListener("click", () => show("success"));
  ng.addEventListener("click", () => show("error"));
</script>
HTML

ここが重要です:toggle(, 条件) で「候補の白リストを一括管理」すると、常に正しいクラス集合に整います。


まとめ

classList.toggle は、クラスを「付ける/外す」を一発で扱えるメソッドです。第二引数で目標状態を明示すれば、add/remove の分岐を一本化でき、排他的クラスの整理も簡潔になります。返り値で UI 文言や aria を同期し、is-* の状態クラスだけを JS で操作する——この設計を徹底すると、初心者でも読みやすく、安全で壊れにくい UI 制御が書けます。

タイトルとURLをコピーしました