JavaScript | DOM 操作:要素の取得 – CSS セレクタの使い分け

JavaScript JavaScript
スポンサーリンク

CSS セレクタの使い分けとは何か

CSS セレクタは、HTML の中から「どの要素を対象にするか」を表す記法で、querySelector / querySelectorAll でもそのまま使えます。id、class、タグ名、属性、階層関係、擬似クラスなどを組み合わせて、狙った要素だけを効率よく取得できます。ここが重要です:セレクタは「短く・安定・意図が明確」が正義。見た目のためのクラスと、JavaScript のフック(id や data-*)を分けると、壊れにくく保守しやすい紐づけになります。


基本セレクタの使い分け(id・class・タグ・属性)

id セレクタ(#id)

一意の要素を最短で取得。ページ内で重複しないことが前提です。

<h1 id="title">こんにちは</h1>
<script>
  const el = document.querySelector("#title");
</script>
HTML

ここが重要です:一意なら id を優先。読みやすく、性能も良いです。

クラスセレクタ(.class)

複数要素のグループを取得。最初の1件なら querySelector、全部なら querySelectorAll。

<p class="msg">A</p><p class="msg">B</p>
<script>
  const first = document.querySelector(".msg");
  const all = document.querySelectorAll(".msg");
</script>
HTML

ここが重要です:見た目用のクラスと、JS 用のクラス(または data-*)は分けると変更に強くなります。

タグセレクタ(div, p など)

広く拾うときに便利。ただし対象が多くなりやすいので、スコープを絞るのが前提。

const firstDiv = document.querySelector("div");
JavaScript

ここが重要です:タグ単体は曖昧になりがち。親要素からの検索で範囲限定をセットで考えましょう。

属性セレクタ([name=”…”] / [data-…])

data-* は JS フックのベストプラクティス。意味のあるメタ情報を持たせやすいです。

<button class="btn" data-role="buy">購入</button>
<script>
  const buy = document.querySelector('.btn[data-role="buy"]');
</script>
HTML

ここが重要です:data-* は「構造や見た目に依存しないフック」。将来の変更に強いです。


階層・関係セレクタ(親子・兄弟で絞る)

子孫(スペース)と直下の子(>)

スペースは「配下すべて」、> は「直下の子」だけ。

<div class="card"><h2 class="title">T</h2></div>
<script>
  const anyDepth = document.querySelector(".card .title");   // 子孫
  const direct    = document.querySelector(".card > .title"); // 直下の子
</script>
HTML

ここが重要です:DOM の入れ子が変わる可能性があるなら子孫、厳密に直下だけなら >。要件に合わせて使い分けます。

兄弟(+ と ~)

  • は直後の兄弟、~ は後続の兄弟すべて。
<label class="switch"></label><input class="field">
<script>
  const nextField = document.querySelector(".switch + .field"); // 直後の兄弟
</script>
HTML

ここが重要です:兄弟セレクタは「並び」に依存します。並び変更に弱いので、優先度は低めに。


状態に応じた擬似クラス(:hover, :focus, :checked, :nth-child)

フォーム状態の取得と制御

選択状態やインデックスで絞り込みができます。DOM 取得では「現時点の条件に合うもの」を取れます。

<form id="prefs">
  <input type="checkbox" class="opt" checked>
  <input type="checkbox" class="opt">
</form>
<script>
  const checked = document.querySelectorAll("#prefs .opt:checked");
  const third   = document.querySelector("#prefs .opt:nth-child(3)");
</script>
HTML

ここが重要です:擬似クラスは強力ですが、動的に変わる条件です。必要ならイベントで再取得し直す設計にします。


セレクタ設計の深掘り(特異性・安定性・短さ)

特異性(specificity)を意識する

id > クラス/属性 > タグ の順に強くなります。JS の取得では「強すぎるセレクタ」は不要です。短く明確に。

// 悪い例:強くて長いセレクタ(変更に弱い)
document.querySelector("main .container .card .header .title");

// 良い例:安定したフック中心(短く、意味が明確)
document.querySelector('[data-role="card-title"]');
JavaScript

ここが重要です:DOM 構造に依存する長いセレクタは壊れやすい。data-* や id を使って短く、目的に直結させます。

スコープで衝突回避

親要素から検索すると、同名クラスが複数あっても混ざりません。

const panel = document.getElementById("panel");
const btn   = panel.querySelector(".btn");
JavaScript

ここが重要です:コンポーネント単位のスコープ設計は、命名の衝突を自然に回避します。

特殊文字のエスケープ

id/class にドットやコロンが入っているときは、バックスラッシュでエスケープします。

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

ここが重要です:エスケープが必要な命名は避けるのが理想。フックはシンプルに。


実践パターン(定番の取り方と落とし穴回避)

コンポーネント内のフック

構造に依存せず、役割ベースで安定取得。

<article class="card" id="product">
  <h2 data-role="title">Title</h2>
  <button data-role="buy">購入</button>
</article>
<script defer>
  const card  = document.querySelector("#product");
  const title = card.querySelector('[data-role="title"]');
  const buy   = card.querySelector('[data-role="buy"]');
</script>
HTML

ここが重要です:data-role のような役割名は、JS から読みやすく、構造変更にも強い。

複数取得と一括処理

静的 NodeList を前提に安定処理。

<div class="product-card"><button class="buy">Buy</button></div>
<div class="product-card"><button class="buy">Buy</button></div>
<script defer>
  const cards = document.querySelectorAll(".product-card");
  cards.forEach(card => {
    const btn = card.querySelector(".buy");
    btn.addEventListener("click", () => card.classList.add("purchased"));
  });
</script>
HTML

ここが重要です:親カードから子を取るスコープ設計で、意図しない混入を防ぎます。

null ガードとタイミング

DOM 未構築で null にならないように、defer か DOMContentLoaded で。

<script>
  document.addEventListener("DOMContentLoaded", () => {
    const el = document.querySelector("#title");
    if (!el) return;
    el.textContent = "ようこそ";
  });
</script>
HTML

ここが重要です:null は珍しくありません。毎回ガードを癖にすると、初期化が堅牢になります。


まとめ

CSS セレクタは、DOM 取得の「表現力」を支える土台です。id は最短で一意、class はグループ、data-* は安定フック、階層・兄弟で必要範囲に絞り、擬似クラスで状態に応じて選べます。セレクタは短く、構造依存を避け、スコープで衝突を回避し、data-* を活用して「役割」で紐づける。null ガードと適切なタイミングを守れば、初心者でも複雑な選択を安全に、読みやすく書けるようになります。

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