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

JavaScript JavaScript
スポンサーリンク

getElementsByTagName とは何か

getElementsByTagName は、指定したタグ名(例: “div”, “p”, “a”)を持つ要素をまとめて取得するメソッドです。返り値は HTMLCollection(ライブコレクション)で、DOM が後から増減すると内容が自動的に更新されます。ここが重要です:ライブであるため、ループ中に対象が増減すると挙動が変わる可能性があります。処理を安定させたいなら、取得直後に配列へ固定化してから扱うのが安全です。


基本の使い方(全ての同種タグを一括取得)

ドキュメント全体から取得

<div>One</div>
<div>Two</div>
<p>Paragraph</p>
<script>
  const divs = document.getElementsByTagName("div"); // HTMLCollection(ライブ)
  console.log(divs.length);     // 2
  console.log(divs[0].textContent); // "One"
</script>
HTML

親要素を起点に範囲を絞って取得

<section id="panel">
  <div>Panel A</div>
  <div>Panel B</div>
</section>
<div>Outside</div>
<script>
  const panel = document.getElementById("panel");
  const innerDivs = panel.getElementsByTagName("div"); // panel配下のみ
  console.log(innerDivs.length); // 2(Outside は含まれない)
</script>
HTML

ここが重要です:document からの取得はページ全体が対象になります。意図しない混入を避けるには、親要素からの取得でスコープを限定しましょう。


ライブ HTMLCollection の挙動(増減に自動追随)

取得後に要素を追加すると件数が増える

const divs = document.getElementsByTagName("div"); // 2件とする

const d = document.createElement("div");
d.textContent = "New";
document.body.append(d);

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

反復処理中の落とし穴(対象が縮む・広がる)

const ps = document.getElementsByTagName("p");
// 悪い例:ループ中にタグを置き換えると集合が変わる可能性
for (let i = 0; i < ps.length; i++) {
  const p = ps[i];
  const span = document.createElement("span");
  span.textContent = p.textContent;
  p.replaceWith(span); // ここで p が消える → ps.length が変化する
}
JavaScript

ここが重要です:ライブコレクションを直接いじりながら走査すると、インデックスがずれて要素を飛ばすことがあります。最初に配列へ固定化して処理するか、ループ開始前に長さを変数へキャプチャして固定長で回しましょう。


配列として扱うコツ(安定さ・可読性を高める)

取得直後に配列へ固定化

const divsLive = document.getElementsByTagName("div");
const divs = Array.from(divsLive); // 静的な配列へ
divs.forEach(el => el.classList.add("processed"));
JavaScript

変換・絞り込み・集計が書きやすくなる

const titles = Array.from(document.getElementsByTagName("h2"))
  .map(el => el.textContent.trim())
  .filter(text => text.length > 0);
JavaScript

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


仕様のポイント(タグ名の大小・ワイルドカード・名前空間)

HTML 文書ではタグ名の大小は区別されません。”DIV” でも “div” でも同じ結果になります。一方、XML/SVG では大小が区別されることがあります。ワイルドカード “*” を指定すると、範囲内の全要素を取得できます(用途は限定的ですが、要素総数の確認や一括走査で便利です)。

document.getElementsByTagName("*"); // すべての要素(HTMLCollection)
document.getElementsByTagName("DIV"); // HTMLでは "div" と同じ
JavaScript

ここが重要です:普段の HTML では小文字で統一すると読みやすく、SVG など名前空間要素を扱うときはタグ名の大小に注意しましょう。


querySelectorAll との使い分け(柔軟性と最新性の比較)

querySelectorAll は CSS セレクタで柔軟に取得でき、返り値は静的 NodeList(後から DOM が変わっても結果は固定)。getElementsByTagName はタグ名だけで高速に取得でき、返り値はライブ HTMLCollection(常に最新)。複雑な条件で絞る、配列メソッドを多用する、処理の安定性を優先するなら querySelectorAll。常時最新の集合を監視したい、タグ単位で広く取って後続処理で判定するなら getElementsByTagName が向いています。

// 静的で安定:タグ+属性まで絞る
const nodes = document.querySelectorAll("div.card[data-active='true']");

// 最新性重視:タグ単位で常時更新される集合
const divs = document.getElementsByTagName("div");
JavaScript

ここが重要です:日常的な UI 処理では静的のほうがバグが少なく、読みやすいことが多いです。ライブは「最新性」に価値がある場面に絞ると扱いやすくなります。


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

DOM 構築前に取得すると null や空集合になることがあります。defer でスクリプトを読み込み、DOM 構築完了直前の安全なタイミングで初期化すると安定します。また、読み取りと書き込みをバッチ化し、見た目の変更はクラス切り替えを基本にすると、再描画コストを抑えられます。

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

ここが重要です:いつ触るか(defer / DOMContentLoaded)、どう変えるか(クラスで一括)を意識するだけで、体感速度と安定性が大きく向上します。


実践例:記事カードの要約を一括整形

<section id="articles">
  <article><h2>タイトルA</h2><p>説明文A ...</p></article>
  <article><h2>タイトルB</h2><p>説明文B ...</p></article>
</section>
<script defer>
  const section = document.getElementById("articles");
  const articles = Array.from(section.getElementsByTagName("article")); // 固定化

  articles.forEach(el => {
    const title = el.getElementsByTagName("h2")[0]?.textContent.trim() || "無題";
    const desc = el.getElementsByTagName("p")[0]?.textContent.trim() || "";
    el.classList.add("card");
    el.setAttribute("data-title", title);
    el.setAttribute("data-length", String(desc.length));
  });
</script>
HTML

ここが重要です:親要素からの範囲取得でスコープを限定し、ライブ集合は配列化して安定処理。内部のタグも getElementsByTagName で素直に取れますが、存在しない可能性に備えて安全な参照([0]?)を徹底しましょう。


まとめ

getElementsByTagName は「タグ名で要素を一括取得」する高速な入り口で、返り値はライブ HTMLCollection。最新性が魅力ですが、反復中の変動でバグが起きやすいため、配列化して固定してから処理するのが安全です。HTML ではタグ名の大小を区別しない、”*” で全要素を取得できる、親要素からの取得でスコープを絞れる——この要点を押さえつつ、複雑な条件や安定した処理が欲しい場合は querySelectorAll を使い分けましょう。タイミングは defer/DOMContentLoaded に合わせ、更新はクラス切り替え中心に。これが、タグベース取得を速く・正確・壊れにくく運用するコツです。

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