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>
HTMLdefer で読み込めば、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>
HTMLdocument.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 に合わせ、変更はクラス切り替えでまとめる——この型を身につければ、クラスベースの要素取得は速く、正確で、壊れにくくなります。
