【JavaScript】タグ名で要素を取得する方法|getElementsByTagName・querySelectorAll・ライブコレクション・実務パターンまで解説

【JavaScript】タグ名で要素を取得する方法|getElementsByTagName・querySelectorAll・ライブコレクション・実務パターンまで解説 JavaScript

getElementsByTagName は HTML のタグ名(p / div / img 等)を指定して要素を取得するメソッドです。現在は querySelectorAll("tag") で代替可能ですが、既存コードの理解や特定の用途(ライブコレクション)で知っておくべき API です。

この記事でわかること
・getElementsByTagName の基本構文と戻り値(HTMLCollection)
・querySelectorAll(“tag”) との違い(ライブ vs 静的)
・親要素内からのスコープ検索
・全要素の取得(ワイルドカード *)
・テーブル操作・画像一括処理・リンク取得の実務パターン
・タグ名取得が最適な場面と querySelector を使うべき場面
スポンサーリンク

getElementsByTagName の基本

JavaScript(基本構文)
// 全ての p 要素を取得
const paragraphs = document.getElementsByTagName("p");
console.log(paragraphs.length); // p 要素の数
console.log(paragraphs[0]);     // 最初の p 要素

// 全ての img 要素を取得
const images = document.getElementsByTagName("img");

// 全ての a 要素を取得
const links = document.getElementsByTagName("a");

// 全要素を取得(ワイルドカード *)
const allElements = document.getElementsByTagName("*");
console.log(allElements.length); // ページ内の全要素数
項目 内容
引数 タグ名(文字列: “p” / “div” / “img” 等)。”*” で全要素
戻り値 HTMLCollection(ライブコレクション)
大文字小文字 HTML では区別しない(”P” も “p” も同じ)
スコープ document または任意の要素から呼び出し可能

querySelectorAll(“tag”) との比較

JavaScript(querySelectorAll で同じことをする)
// getElementsByTagName と同等
const paragraphs = document.querySelectorAll("p");

// querySelectorAll はさらに複合条件が可能
const mainParagraphs = document.querySelectorAll("main p");
const firstP = document.querySelectorAll("p:first-child");
const boldLinks = document.querySelectorAll("a.bold");
項目 getElementsByTagName querySelectorAll(“tag”)
戻り値 HTMLCollection(ライブ) NodeList(静的)
DOM 変更の反映 リアルタイムに反映 取得時点のスナップショット
forEach 使えない(Array.from 必要) 直接使える
複合セレクタ 不可(タグ名のみ) 可能(”div.card” / “ul > li” 等)
速度 わずかに速い 実測差なし(体感不可)
推奨 既存コードの保守・ライブが必要な場合 新規コードでは推奨
新規コードでは querySelectorAll を推奨
querySelectorAll は CSS セレクタの複合条件が使え、forEach も直接使えるため、新規コードでは querySelectorAll に統一する方が合理的です。getElementsByTagName を選ぶ理由は「ライブコレクションが必要」「微小な速度差が重要(数万要素のループ等)」の場合のみです。

ライブコレクション(HTMLCollection)の特性

JavaScript(ライブコレクションの動作)
// getElementsByTagName はライブ
const items = document.getElementsByTagName("li");
console.log(items.length); // 3

// DOM に li を追加
const newLi = document.createElement("li");
newLi.textContent = "New Item";
document.querySelector("ul").appendChild(newLi);

// items の length が自動更新される!
console.log(items.length); // 4(再取得不要)

// querySelectorAll は静的(更新されない)
const staticItems = document.querySelectorAll("li");
// DOM に追加しても staticItems.length は 3 のまま
ループ中の DOM 変更に注意
ライブコレクションはループ中に要素を追加・削除するとリアルタイムで中身が変わり、無限ループやスキップの原因になります。ループ中に DOM を変更する場合は querySelectorAll(静的)を使うか、逆順ループにしてください。
JavaScript(ライブコレクションの罠と対策)
// NG: ループ中に要素を削除するとスキップが発生
// const items = document.getElementsByTagName("li");
// for (let i = 0; i < items.length; i++) {
//   items[i].remove(); // length が変わりスキップ!
// }

// OK(1): 逆順ループ
const items = document.getElementsByTagName("li");
for (let i = items.length - 1; i >= 0; i--) {
  items[i].remove(); // 逆順なら安全
}

// OK(2): querySelectorAll(静的)を使う
document.querySelectorAll("li").forEach(li => li.remove());

親要素内からタグ名で検索

JavaScript(スコープ付き検索)
// 特定の親要素内のタグだけ取得
const nav = document.querySelector("nav");
const navLinks = nav.getElementsByTagName("a");
console.log(navLinks.length); // nav 内の a 要素だけ

// querySelectorAll でも同等
const navLinks2 = nav.querySelectorAll("a");

// テーブル内の td だけ取得
const table = document.querySelector("#data-table");
const cells = table.getElementsByTagName("td");

特殊なショートカットプロパティ

一部のタグには専用のプロパティが用意されており、getElementsByTagName を使わずにアクセスできます。

プロパティ 同等の getElementsByTagName 戻り値
document.images getElementsByTagName(“img”) HTMLCollection(全 img)
document.links getElementsByTagName(“a”)(href 付きのみ) HTMLCollection(href 付き a + area)
document.forms getElementsByTagName(“form”) HTMLCollection(全 form)
document.scripts getElementsByTagName(“script”) HTMLCollection(全 script)
table.rows HTMLCollection(テーブルの全 tr)
tr.cells HTMLCollection(行内の全 td / th)
JavaScript(ショートカットプロパティ)
// 全画像
console.log(document.images.length);

// 全フォーム
console.log(document.forms.length);
console.log(document.forms[0].action); // 最初のフォームの action

// テーブルの全行
const table = document.querySelector("#data-table");
console.log(table.rows.length); // 行数
console.log(table.rows[0].cells.length); // 最初の行のセル数

実務パターン集

パターン(1): 全画像に loading=”lazy” を追加

JavaScript
document.querySelectorAll("img").forEach(img => {
  if (!img.hasAttribute("loading")) {
    img.setAttribute("loading", "lazy");
  }
});

パターン(2): テーブルの行を操作

JavaScript
// テーブルの偶数行にクラスを付与
const rows = document.querySelector("#data-table").rows;
for (let i = 0; i < rows.length; i++) {
  if (i % 2 === 1) rows[i].classList.add("even-row");
}

// CSS だけでも可能: tr:nth-child(even) { background: #f8f8f8; }

パターン(3): 全外部リンクに rel 属性を追加

JavaScript
[...document.links].forEach(link => {
  if (link.hostname !== location.hostname) {
    link.setAttribute("rel", "noopener noreferrer");
    link.setAttribute("target", "_blank");
  }
});

パターン(4): 特定タグの要素数をカウント

JavaScript
// ページ内の要素数を集計(デバッグ用)
const tags = ["div", "p", "span", "a", "img", "table"];
tags.forEach(tag => {
  const count = document.getElementsByTagName(tag).length;
  if (count > 0) console.log(`<${tag}>: ${count} 個`);
});

パターン(5): ページ内の全要素数

JavaScript
// ワイルドカード * で全要素を取得
const total = document.getElementsByTagName("*").length;
console.log(`ページ内の全要素数: ${total}`);

getElementsByTagName を使うべき場面

場面 推奨メソッド 理由
タグ名だけで全要素取得(新規コード) querySelectorAll(“tag”) forEach が使える。複合条件にも拡張可能
ライブコレクションが必要 getElementsByTagName DOM の追加/削除がリアルタイムに反映される
既存コードの保守 getElementsByTagName そのまま動作するため無理に書き換え不要
テーブルの行/セル操作 table.rows / tr.cells 専用プロパティが最もシンプル
全画像 / 全フォーム / 全リンク document.images / forms / links 専用ショートカット

よくある質問

QgetElementsByTagName と querySelectorAll はどちらが速いですか?
A技術的には getElementsByTagName の方がわずかに速いですが、実測で体感できる差はありません。数万要素を繰り返し取得するベンチマークでのみ差が出ます。通常の開発では速度よりも可読性と機能性で querySelectorAll を選んでください。
Qタグ名は大文字で指定しても動きますか?
Aはい。HTML ドキュメントでは getElementsByTagName("P")getElementsByTagName("p") は同じ結果です。ただし XML ドキュメント(XHTML)では大文字小文字が区別されます。
QgetElementsByTagName(“*”) は何に使いますか?
Aページ内の全要素を取得します。要素数のカウント、特定の属性を全要素からチェックする、DOM ツリーの分析などのデバッグ・分析用途で使われます。通常の開発では使う機会は少ないです。
QHTMLCollection に forEach が使えません
AgetElementsByTagName が返す HTMLCollection には forEach がありません。Array.from(collection).forEach(...) または [...collection].forEach(...) で配列に変換してから使ってください。querySelectorAll の NodeList なら forEach が直接使えます。
Qdocument.images と getElementsByTagName(“img”) は同じですか?
Aほぼ同じですが、document.images は DOM の標準プロパティとして直接アクセスでき、より高速です。どちらもライブの HTMLCollection を返します。
QSVG 要素も getElementsByTagName で取得できますか?
Aはい。getElementsByTagName("svg")getElementsByTagName("circle") で SVG 要素を取得できます。ただし名前空間が異なる場合は getElementsByTagNameNS を使う必要があります。通常の HTML 埋め込み SVG なら問題ありません。

まとめ

タグ名による要素取得の要点をまとめます。

やりたいこと 推奨方法
タグ名で全要素を取得(推奨) document.querySelectorAll(“tag”)
タグ名で全要素を取得(ライブ) document.getElementsByTagName(“tag”)
親要素内からタグで検索 parent.querySelectorAll(“tag”) / parent.getElementsByTagName(“tag”)
全画像を取得 document.images
全リンクを取得 document.links
全フォームを取得 document.forms
テーブルの全行を取得 table.rows
ページ内の全要素数 document.getElementsByTagName(“*”).length

ID での取得は「ID で要素を取得する方法」、クラスでの取得は「クラス名で要素を取得する方法」、querySelector の詳細は「querySelector / querySelectorAll の使い方」も併せて参照してください。