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

JavaScript JavaScript
スポンサーリンク

getElementsByClassName とは何か

getElementsByClassName は、「指定したクラス名を持つ要素をまとめて取得する」ためのメソッドです。返り値は HTMLCollection(ライブコレクション)で、後から DOM が増減すると内容が自動で更新されます。ここが重要です:ライブであることが最大の特徴です。ページの状態が変わると取得済みの集合も変わるため、反復処理中に件数が変わる可能性を常に意識しましょう。


基本の使い方(複数要素を即取得)

同じクラスを持つ要素を全部取る

<ul>
  <li class="item">A</li>
  <li class="item">B</li>
  <li class="item">C</li>
</ul>
<script>
  const items = document.getElementsByClassName("item"); // HTMLCollection(ライブ)
  console.log(items.length);  // 3
  console.log(items[0].textContent); // "A"
</script>
HTML

親要素から部分範囲で取得(スコープを絞る)

<div id="panel">
  <button class="btn">OK</button>
  <button class="btn">Cancel</button>
</div>
<script>
  const panel = document.getElementById("panel");
  const buttons = panel.getElementsByClassName("btn");  // panel配下のみ
  console.log(buttons.length); // 2
</script>
HTML

ここが重要です:document からだけでなく「親要素からの取得」も使えるため、影響範囲を絞れます。スコープを限定すると、意図しない要素混入を防げます。


ライブな HTMLCollection の挙動(深掘り)

取得後に DOM を変えるとコレクションも変わる

const items = document.getElementsByClassName("item"); // 3件あったとする
const ul = document.querySelector("ul");

const li = document.createElement("li");
li.className = "item";
ul.append(li);

console.log(items.length); // 4(ライブなので自動で増える)
JavaScript

反復中の変動で起きる落とし穴

const buttons = document.getElementsByClassName("btn");
// 悪い例:ループ中にクラスを外すと、集合から消えてインデックスがズレる
for (let i = 0; i < buttons.length; i++) {
  buttons[i].classList.remove("btn"); // 集合が縮む→要素を飛ばす可能性
}
JavaScript

ここが重要です:ライブ集合を直接いじると「走査しながら対象が消える」ことがあります。ループ前に配列へ固定化するのが安全策です。


配列として扱う(安定した処理にするコツ)

まずは Array に変換してから処理

const live = document.getElementsByClassName("item");
const arr = Array.from(live);  // 静的な配列に固定
arr.forEach(el => el.classList.add("bound")); // 安定して一括処理
JavaScript

よく使う変換+絞り込み・変換パターン

const cards = Array.from(document.getElementsByClassName("card"))
  .filter(el => el.dataset.active === "true")
  .map(el => el.querySelector(".title").textContent);
JavaScript

ここが重要です:map/filter/reduce を使いたいなら必ず配列化。処理途中で DOM が変わっても結果がブレません。


複数クラスと検索仕様(誤解しがちなポイント)

スペース区切りで「すべてのクラスを持つ要素」を検索

<div class="btn primary"></div>
<div class="btn"></div>
<script>
  const both = document.getElementsByClassName("btn primary");
  console.log(both.length); // "btn"と"primary"の両方を持つ要素のみ(1)
</script>
HTML

部分一致ではない(“pri” ではヒットしない)

document.getElementsByClassName("pri"); // "primary"の部分一致にはならない → 0件
JavaScript

ここが重要です:判定はクラス名の完全一致。複数指定は「AND条件」。曖昧検索はできないため、必要なら querySelector の属性セレクタなどを使いましょう。


querySelectorAll との使い分け(静的 vs ライブ)

柔軟な CSS セレクタが必要なら querySelectorAll(静的)

// 子孫の条件や属性、状態まで含めて絞りたい
const nodes = document.querySelectorAll(".card > .title[data-level='2']");
JavaScript

クラス単体で常時最新を見たいなら getElementsByClassName(ライブ)

const liveButtons = document.getElementsByClassName("btn"); // 追加・削除に追随
JavaScript

ここが重要です:複雑な条件や配列メソッド前提の処理は静的(querySelectorAll)に寄せると読みやすく、バグが減ります。ライブは「最新性に価値がある場面」に限定すると扱いが楽です。


パフォーマンスとタイミング(安全に速く)

タイミングは DOM 構築後に合わせる

<script defer src="app.js"></script>
HTML

defer で読み込めば、DOM 構築完了直前に実行され、要素取得の null リスクが減ります。

無駄な再計算を避ける(読み書きのバッチ化)

  • 複数要素に同じ変更を適用するなら、クラス切り替えで CSS に任せる。
  • 大量追加は DocumentFragment にまとめて挿入する。
    ここが重要です:DOM の読み取りと書き込みをまとめるだけで、ページの体感速度は上がります。

実践例:インベントリ表示の更新

<ul id="stock">
  <li class="item" data-qty="0">Apple</li>
  <li class="item" data-qty="5">Banana</li>
  <li class="item" data-qty="2">Cherry</li>
</ul>
HTML
document.addEventListener("DOMContentLoaded", () => {
  const stock = document.getElementById("stock");
  const items = Array.from(stock.getElementsByClassName("item")); // 配列化で固定

  items.forEach(el => {
    const qty = Number(el.dataset.qty);
    el.classList.toggle("is-out", qty === 0);
    el.classList.toggle("is-low", qty > 0 && qty <= 3);
    el.classList.toggle("is-ok", qty > 3);
  });

  // 後から追加しても、ライブ取得なら追随可能
  const li = document.createElement("li");
  li.className = "item";
  li.textContent = "Durian";
  li.dataset.qty = "1";
  stock.append(li); // stock.getElementsByClassName("item") は件数が増える
});
JavaScript

ここが重要です:処理の安定性重視なら配列化してからまとめて更新。追加・削除の監視が必要ならライブコレクションを保持しておくと、後続処理で最新集合を参照できます。


まとめ

getElementsByClassName は「クラス名で要素を集める」ための高速な入り口で、返り値はライブ HTMLCollection。ライブは常時最新が魅力ですが、ループ中に内容が変わるリスクがあるため、配列化して固定してから処理するのが安全です。複雑な条件には querySelectorAll(静的)を使い、クラス指定は完全一致・複数指定は AND 条件という仕様を押さえる。タイミングは defer/DOMContentLoaded に合わせ、変更はクラス切り替えでまとめる——この型を身につければ、クラスベースの要素取得は速く、正確で、壊れにくくなります。

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