DOMの操作(読み取り)— 要素の取得方法
DOMから要素を取得する代表的なAPIは次の4系統です。目的(唯一の要素を欲しいのか、複数か、表現力か、速度か)と返り値の型(単一要素/コレクション)、コレクションがライブか静的かを押さえると使い分けが明確になります。
共通のポイント(前提)
-
どのメソッドも
documentだけでなく 任意の要素を起点に呼び出せます(探索範囲をその要素の子孫に限定できる)。-
例:
sectionEl.querySelectorAll('a')
-
-
ライブ(動的)コレクションは DOM 変更を自動反映、静的コレクションは取得時点のスナップショットです。
-
反復時は
for...ofやforEach、配列化(Array.from()、スプレッド)を使うと扱いやすいです。
1) getElementById(id)
getElementById(id)-
用途: 一意のIDを持つ要素を1つ取得。
-
返り値:
Element | null -
探索対象: ドキュメント全体(※要素からは呼べません。常に
document.getElementById) -
特徴:
-
最速クラス(ブラウザが内部に索引を持つため)。
-
同じIDが複数あると最初の1つだけ返り、HTMLの仕様上はIDは一意が前提。
-
-
例:
2) getElementsByClassName(classNames)
getElementsByClassName(classNames)-
用途: クラス名で複数一致を取得。
-
引数: 文字列(スペース区切りで AND 条件)。
"btn primary"は両方のクラスを持つ要素のみ一致。 -
返り値:
HTMLCollection(ライブ) -
探索対象: 呼び出し元の要素配下(
documentまたは任意要素) -
注意:
-
ライブなので、取得後にDOMを追加・削除すると自動で内容が変わる。反復中の変更で取りこぼしが起きやすい。
-
反復や安全な操作をしたいときは 配列にコピーする。
-
-
例:
3) getElementsByTagName(tagName)
getElementsByTagName(tagName)-
用途: タグ名で複数一致を取得(例:
"li","p")。"*"で全要素。 -
返り値:
HTMLCollection(ライブ) -
探索対象: 呼び出し元の要素配下
-
注意:
-
HTML文書ではタグ名の大小は区別されません(XMLでは区別される)。
-
大量要素を一気に取る用途に向くが、ライブである点は要注意。
-
-
例:
4) querySelector(selector) / querySelectorAll(selector)
querySelector(selector) / querySelectorAll(selector)-
用途: CSSセレクタで柔軟に検索。
-
querySelectorは最初に一致した1要素 -
querySelectorAllは全一致(静的 NodeList)
-
-
返り値:
-
querySelector:Element | null -
querySelectorAll:NodeList(静的。forEach可)
-
-
探索対象: 呼び出し元の要素配下
-
セレクタ例:
-
'#app .item.active'(ID → クラス → 状態) -
'a[href^="/docs/"]'(前方一致) -
':scope > li:nth-child(2)'(:scopeは呼び出し元要素を基点に明示)
-
-
注意:
-
静的なので、DOM変更後は再度呼び直す必要がある。
-
表現力が高く読みやすいが、単純取得では
getElementByIdの方が速く意図も明確。
-
-
例:
ライブ vs 静的 の落とし穴と対処
-
落とし穴: ライブな
HTMLCollectionを前から削除しながら反復すると、インデックスが詰まって要素をスキップする場合がある。 -
対処:
-
配列にコピーしてから処理:
Array.from(collection).forEach(...) -
末尾から逆順で処理:
for (let i = collection.length - 1; i >= 0; i--) { ... } -
そもそも静的な
querySelectorAllを使う。
-
スコープの設定(document か要素か)
-
大きなページ全体から取るより、起点要素を絞ってから検索すると可読性・性能が上がります。
どれを選ぶべきか(指針)
-
一意の要素が欲しい →
getElementById(最速・意図が明確) -
多数の同種要素でクラスやタグが決まっている →
getElementsByClassName/getElementsByTagName(ただしライブに注意) -
柔軟な条件や複合条件が必要 →
querySelector/querySelectorAll(静的で安全、CSSセレクタで表現力)
まとめ表
| メソッド | 目的 | 返り値 | コレクション性 | ライブ/静的 | スコープ |
|---|---|---|---|---|---|
getElementById |
一意IDで1件取得 | `Element | null` | 単一 | ― |
getElementsByClassName |
クラス一致(AND可) | HTMLCollection |
複数 | ライブ | document/要素 |
getElementsByTagName |
タグ一致("*"可) |
HTMLCollection |
複数 | ライブ | document/要素 |
querySelector |
CSSで最初の一致 | `Element | null` | 単一 | ― |
querySelectorAll |
CSSで全一致 | NodeList |
複数 | 静的 | document/要素 |
小さな実践例(4種を一度に体験)
補足の注意点
-
getElementsByClassName("a b")は a と b の両方を持つ要素のみ一致します。順序は不問。 -
querySelectorAllのNodeListはforEachを持ちますが、mapなど配列メソッドはないため必要に応じて配列化します。 -
大規模な探索は 起点を絞るか、セレクタを具体的にして過剰マッチを避けると効率的です。
-
HTMLではIDは一意であるべきです。重複IDは選択結果やアクセシビリティの問題を招きます。
この4系統を「一意か複数か」「表現力」「ライブか静的か」で選び分けると、意図どおりで安全・効率的な DOM 取得ができます。
ChatGPT5 生成日:2025/09/11