JavaScript | DOM 操作:要素の取得 – matches

JavaScript JavaScript
スポンサーリンク

matches とは何か

matches は、ある要素が「指定した CSS セレクタに現在一致しているか」を真偽値で返すメソッドです。ここが重要です:取得した要素に対して直接判定できるため、「このクリック元がターゲットか」「このカードはアクティブ条件に合うか」などを高速・簡潔に書けます。セレクタは querySelector と同じ文法で使えます。


基本の使い方(その場でセレクタ適合をチェック)

単純な判定

<button class="btn primary">購入</button>
<script>
  const btn = document.querySelector("button");
  console.log(btn.matches(".btn"));           // true
  console.log(btn.matches(".secondary"));     // false
  console.log(btn.matches("button.primary")); // true
</script>
HTML

要素を探してから「この要素が条件に合うか」を即判定できます。ここが重要です:matches は「再検索せずに済む」ので、読みやすく効率的です。

状態に依存する判定(擬似クラス)

<input id="agree" type="checkbox" checked>
<script>
  const box = document.querySelector("#agree");
  console.log(box.matches(":checked")); // true(現時点の状態)
</script>
HTML

擬似クラスも使えます。現在の状態に応じた分岐がシンプルに書けます。


イベント委譲での実践(ターゲット判定の定番)

親一箇所にだけイベントを登録

<ul id="menu">
  <li><button class="item" data-key="a">A</button></li>
  <li><button class="item" data-key="b">B</button></li>
</ul>
<script defer>
  const menu = document.getElementById("menu");

  menu.addEventListener("click", (e) => {
    const target = e.target;
    if (!(target instanceof Element)) return;

    if (target.matches("button.item")) {
      const key = target.dataset.key;
      console.log("clicked:", key);
    }
  });
</script>
HTML

ここが重要です:クリックの発生源が「欲しいボタンか」を matches で即チェック。親に一度だけイベントを置く“委譲”と相性が抜群で、要素の追加・削除にも強い設計になります。


closest と組み合わせる(発生源が深い位置でも安全)

深い位置でクリックされても祖先を特定して判定

<div class="card">
  <button class="buy"><span>購入</span></button>
</div>
<script defer>
  document.addEventListener("click", (e) => {
    const el = e.target;
    if (!(el instanceof Element)) return;

    const btn = el.closest("button.buy");
    if (btn && btn.matches(".buy")) {
      // ここに購入ボタンの処理
    }
  });
</script>
HTML

ここが重要です:span をクリックしても、closest でボタンを引き上げ、最後に matches で条件を確定。DOM 入れ子に強く、誤判定を防げます。


セレクタ設計の勘所(読みやすさと安定性を優先)

data-* を使うと変更に強い

<button class="btn" data-role="buy">購入</button>
<script>
  const btn = document.querySelector(".btn");
  if (btn.matches('[data-role="buy"]')) {
    // 役割に基づいた処理
  }
</script>
HTML

ここが重要です:見た目用クラスより「役割フック(id や data-*)」で判定すると、レイアウト変更に強く保守性が上がります。matches のセレクタは短く明確に。

特殊文字を含む id/クラスはエスケープ

<div id="user.name"></div>
<script>
  const el = document.querySelector("#user\\.name");
  console.log(el.matches("#user\\.name")); // true
</script>
HTML

セレクタにドットやコロンが入る命名は避けるのが理想です。必要ならバックスラッシュでエスケープします。


よくある落とし穴(境界・対象の型・パフォーマンス)

テキストノードは matches できない

イベントの target はテキストノードの場合があります。必ず Element かどうかを確認してから使いましょう。

if (!(e.target instanceof Element)) return;
JavaScript

範囲外のクリックを除外する

特定コンテナ内だけで動かしたい場合は、contains と併用します。

const root = document.querySelector(".root");
document.addEventListener("click", (e) => {
  const t = e.target;
  if (!(t instanceof Element)) return;
  if (!root.contains(t)) return; // root外は無視
  if (t.matches(".action")) { /* … */ }
});
JavaScript

ここが重要です:型ガード(Element かどうか)と範囲ガード(contains)を癖にすると、イベント処理の安定性が格段に上がります。matches は軽い判定なので、必要に応じて何度でも使えますが、同じ複雑セレクタの再判定は避け、結果は変数に保持すると読みやすくなります。


実践例:フォームの検証と動的クラス切り替え

<form id="contact">
  <input class="field" name="email" type="email">
  <input class="field" name="name"  type="text">
  <button class="submit">送信</button>
</form>
<script defer>
  const form = document.getElementById("contact");

  form.addEventListener("input", (e) => {
    const el = e.target;
    if (!(el instanceof Element)) return;

    if (el.matches('input.field[name="email"]')) {
      el.classList.toggle("is-valid", el.validity.valid);
    }
    if (el.matches('input.field[name="name"]')) {
      el.classList.toggle("is-valid", el.value.trim().length > 0);
    }
  });

  form.addEventListener("click", (e) => {
    const el = e.target;
    if (!(el instanceof Element)) return;
    if (el.matches("button.submit")) {
      e.preventDefault();
      // 送信処理…
    }
  });
</script>
HTML

ここが重要です:イベントの発生源に対して matches で「どのフィールドか」を即判定し、条件に応じてクラスを切り替える。分岐は短く明確、DOM 構造変更にも強い形になります。


まとめ

matches は「この要素がセレクタに適合するか」を一瞬で判定できるメソッドです。イベント委譲との相性がよく、発生源の要素がターゲットかどうかを簡潔に判断できます。上方向の特定には closest、下方向の検索には querySelector を組み合わせ、セレクタは役割フック(id・data-*)で短く明確に。型ガードと範囲ガードを癖にすれば、初心者でも安全で読みやすいイベント処理・DOM 判定が書けるようになります。

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