【JavaScript】クラスも属性も一発判定!matches()メソッドでCSSセレクタを使った条件判定

JavaScriptで「クリックされた要素が特定のクラスを持っているか?」を判定する時、element.classList.contains('クラス名') を使うことが多いと思います。

しかし、JavaScriptにはもっと便利な matches() というメソッドが存在します!

matches() は、引数に「CSSセレクタ」をそのまま渡すことができ、その要素がセレクタに一致していれば true を返してくれます。これにより、クラス名だけでなく「特定のデータ属性を持っているか」「無効化(disabled)されているか」など、複雑な条件もたった1行で判定できるようになります!

今回は、 matches() の使い方をデモと一緒にご紹介します!

デモ動作

See the Pen matches()メソッドで要素を判定する by mikanbako (@mikanbako) on CodePen.

全画面でのデモ動作は以下のリンクからご確認下さい!(別タブで開かれます)

実装コード紹介

【HTML】

<div class="l-wrap">
  <h2>matches() 判定デモ</h2>
  <p class="p-desc">それぞれのボタンをクリックして、判定結果を確認してください!</p>
  
  <div class="p-demo-box">
    <!-- 1. 特定のクラスを持つボタン -->
    <button class="c-btn is-special js-target-btn">スペシャルボタン<br>(.is-special)</button>
    
    <!-- 2. データ属性を持つボタン -->
    <button class="c-btn js-target-btn" data-role="admin">管理者ボタン<br>(data-role="admin")</button>
    
    <!-- 3. 順番(疑似クラス)の判定 -->
    <button class="c-btn js-target-btn">最後のボタン<br>(:last-child)</button>
  </div>

  <!-- 判定結果を表示するエリア -->
  <div class="c-log-box js-log-box">判定結果がここに表示されます</div>
</div>

【CSS】

/* ベース装飾 */
.l-wrap { 
  max-width: 800px;
  margin: 0 auto;
  padding: 40px 20px;
  color: #3e3e3e;
  text-align: center;
}
h2 { 
  font-size: 16px;
  color: #1bb4d4;
  margin-bottom: 16px;
}
.p-desc { 
  font-size: 16px;
  font-weight: bold;
  line-height: 1.6;
  color: #666;
  margin-bottom: 40px;
}

/* ボタンの装飾 */
.p-demo-box {
  display: flex;
  flex-direction: column;
  gap: 16px;
  align-items: center;
  margin-bottom: 30px;
}
.c-btn {
  padding: 12px 30px;
  font-size: 16px;
  font-weight: bold;
  color: #fff;
  background-color: #1bb4d4;
  border-radius: 6px;
  cursor: pointer;
  width: 300px;
  transition: opacity 0.2s ease-out;
}
.c-btn:hover { 
  opacity: 0.8;
}
.c-btn.is-special { 
  background-color: #e83e8c;
}
.c-btn:last-child { 
  background-color: #ccc;
}

/* ログ画面 */
.c-log-box {
  background: #222;
  color: #0f0;
  padding: 16px;
  border-radius: 6px;
  font-family: monospace;
  font-size: 16px;
}

【JavaScript】

const targetBtns = document.querySelectorAll('.js-target-btn');
const logBox = document.querySelector('.js-log-box');

targetBtns.forEach((btn) => {
  btn.addEventListener('click', (e) => {
    // クリックされた要素を変数に格納
    const clickedElement = e.currentTarget;
    let resultText = "";

    // 💡 1. クラス名の判定(contains の代わり)
    if (clickedElement.matches('.is-special')) {
      resultText = "✅ .is-special クラスを持っています!";
    }
    
    // 💡 2. データ属性の判定
    else if (clickedElement.matches('[data-role="admin"]')) {
      resultText = "✅ data-role属性が admin になっています!";
    }
    
    // 💡 3. 状態・順番(疑似クラス)の判定
    else if (clickedElement.matches(':last-child')) {
      resultText = "✅ このボタンは親要素の中で最後(:last-child)の要素です!";
    }
    
    else {
      resultText = "どれにもマッチしませんでした。";
    }

    // 結果を出力
    logBox.textContent = resultText;
  });
});

コードの解説・仕組み

なぜ matches() が便利なのか?

// 💡 1. クラス名の判定(contains の代わり)
if (clickedElement.matches('.is-special')) {
    ...
}
    
// 💡 2. データ属性の判定
else if (clickedElement.matches('[data-role="admin"]')) {
    ...
}
    
// 💡 3. 状態・順番(疑似クラス)の判定
else if (clickedElement.matches(':last-child')) {
    ...
}

従来の classList.contains('is-special') は「クラス」しか判定できませんでした。もしデータ属性を判定したい場合は getAttribute('data-role') === 'admin' と書く必要があり、条件によってメソッドを使い分ける必要がありました。

しかし matches() を使えば、「CSSで要素を指定するときの書き方」をそのまま文字列として渡すだけで判定できます!

  • matches('.is-special') (クラス判定)
  • matches('.is-active, .is-current')(複数クラス判定)
  • matches('[data-role="admin"]') (属性判定)
  • matches(':last-child') (状態判定)

CSSの知識がそのままJSの条件分岐に活かせるため、コードが直感的になり、記述量も減らすことができるのが最大のメリットです。

※よくある活用例
今回の :last-child の他にも、チェックボックスやラジオボタンが選択されているかを判定する matches(':checked') は、フォームバリデーションなどで頻繁に使用される定番テクニックです!

補足:対応ブラウザ状況

より詳しい仕様や最新の対応状況については、以下の公式ドキュメントをご参照ください。

MDN: matches()

まとめ

今回は、要素の条件判定をシンプルにする matches() メソッドをご紹介しました。

クラス名の有無だけでなく、要素の状態や、特定のデータ属性の判定など、幅広いシーンで活用できる非常に強力なメソッドです。

JavaScriptとCSSは密接に関わり合っているため、CSSセレクタの知識をそのまま流用できるこの書き方は、フロントエンド開発においてとても理にかなっています。ぜひご自身のコードでも matches() を取り入れてみてください!

Prev
Next