JavaScriptを使用してWebサイトに動きをつける際、まず最初に行うべき作業は対象となるHTML要素の取得です。
DOM(Document Object Model)を操作することで、ユーザーの操作に応じてテキストを書き換えたり、新しいコンテンツを動的に追加したりすることが可能になります。
2026年現在のフロントエンド開発においても、ライブラリやフレームワークの内部では依然として基本的な要素取得のメソッドが重要な役割を果たしています。
この記事では、JavaScriptで要素を取得するための標準的な方法から、最新のベストプラクティスまでを詳しく解説します。
最も汎用的なquerySelectorとquerySelectorAll
現代のJavaScript開発において、最も頻繁に使用されるのがquerySelectorとquerySelectorAllです。
これらのメソッドはCSSセレクタを使用して要素を指定できるため、非常に柔軟で直感的な記述が可能です。
単一の要素を取得するquerySelector
document.querySelector()は、指定したCSSセレクタに一致する最初の要素を1つだけ返します。
ID、クラス名、タグ名だけでなく、属性セレクタや擬似クラスを組み合わせて詳細に条件を指定できる点が大きなメリットです。
// IDが "main-title" の要素を取得する
const title = document.querySelector('#main-title');
// classが "description" である最初のp要素を取得する
const desc = document.querySelector('p.description');
// 属性セレクタを使用して、特定の名前を持つinput要素を取得する
const emailInput = document.querySelector('input[name="email"]');
console.log(title.textContent);
こんにちは、JavaScriptの世界へ!
もし条件に一致する要素が見つからなかった場合、このメソッドはnullを返すという特性があります。
そのため、取得した要素に対して操作を行う前に、存在確認を行うことが推奨されます。
複数の要素を取得するquerySelectorAll
複数の要素をまとめて取得したい場合には、document.querySelectorAll()を使用します。
このメソッドは、指定したセレクタに一致するすべての要素を含むNodeListを返します。
// すべてのリストアイテム(li)を取得する
const items = document.querySelectorAll('.list-item');
// NodeListに対してforEachメソッドを使い、各要素のテキストを表示する
items.forEach((item, index) => {
console.log(`要素 ${index + 1}: ${item.textContent}`);
});
要素 1: ホーム
要素 2: サービス
要素 3: お問い合わせ
querySelectorAllで取得されるNodeListは静的なコレクションであり、取得した後にDOMが変更されても中身が更新されないという点に注意が必要です。
特定の属性に特化した取得メソッド
CSSセレクタを使用するメソッド以外にも、特定の属性に基づいて要素を高速に取得するための古いメソッドが存在します。
これらは特定の条件下ではquerySelectorよりもパフォーマンスが優れている場合があります。
getElementByIdによる高速な取得
document.getElementById()は、特定のIDを持つ要素を直接取得するためのメソッドです。
IDはHTMLドキュメント内で一意(ユニーク)である必要があるため、ブラウザはこのメソッドを非常に効率的に処理できます。
// ID指定で要素を取得する(#は不要)
const header = document.getElementById('main-header');
console.log(header.tagName);
HEADER
パフォーマンスが極めて重要視される大規模なアプリケーションのループ内などでは、今でも重宝されるメソッドです。
getElementsByClassNameとgetElementsByTagName
クラス名やタグ名で複数の要素を取得するメソッドとして、getElementsByClassNameやgetElementsByTagNameがあります。
これらのメソッドはHTMLCollectionという「生きている(Live)」コレクションを返します。
// クラス名で要素を取得する
const buttons = document.getElementsByClassName('btn-primary');
// 要素の数を確認する
console.log(`ボタンの数: ${buttons.length}`);
ボタンの数: 3
「生きている」コレクションとは、DOMの状態が変化すると自動的にコレクションの内容も同期される仕組みのことです。
この挙動は意図しないバグの原因になることもあるため、特別な理由がない限りはquerySelectorAllを利用するのが一般的です。
要素取得メソッドの比較まとめ
それぞれのメソッドには特徴があり、用途に応じて使い分けることが求められます。
主なメソッドの違いを下表にまとめました。
| メソッド名 | 指定方法 | 戻り値の型 | ライブ更新 |
|---|---|---|---|
| getElementById | ID名 | Element または null | なし |
| querySelector | CSSセレクタ | Element または null | なし |
| querySelectorAll | CSSセレクタ | NodeList | なし |
| getElementsByClassName | クラス名 | HTMLCollection | あり |
| getElementsByTagName | タグ名 | HTMLCollection | あり |
相対的な位置関係で要素を探索する方法
既に取得している要素を起点として、その親、子、あるいは兄弟要素を取得したい場面も多くあります。
これを「DOMツリーの走査(Traversing)」と呼びます。
親要素へのアクセス
ある要素の直上の親要素を取得するには、parentElementプロパティを使用します。
また、特定の条件に合致する最も近い親要素(先祖要素)を探したい場合は、closest()メソッドが非常に便利です。
const child = document.querySelector('.child-element');
// 直近の親要素を取得
const parent = child.parentElement;
// 指定したセレクタに一致する最も近い先祖要素を取得
const wrapper = child.closest('.card-container');
console.log(wrapper.className);
card-container
closest()は、自分自身がセレクタに一致する場合は自分自身を返すという性質を持っています。
子要素と兄弟要素の取得
子要素の一覧を取得するにはchildrenプロパティを、前後の兄弟要素を取得するにはpreviousElementSiblingやnextElementSiblingを使用します。
これらはテキストノード(改行や空白)を無視して、HTMLタグ要素のみを対象とするため使い勝手が良いのが特徴です。
const list = document.querySelector('ul');
// 最初の子要素を取得
const firstItem = list.firstElementChild;
// 次の兄弟要素を取得
const secondItem = firstItem.nextElementSibling;
console.log(secondItem.textContent);
2番目の項目
安全に要素を操作するための最新の書き方
2026年のJavaScript開発では、要素が見つからなかった場合のエラーを未然に防ぐ安全なコード記述が重視されます。
特に、オプショナルチェイニング(Optional Chaining)の活用は必須と言えるでしょう。
オプショナルチェイニングによるエラー回避
querySelectorで要素が取得できなかった場合、戻り値はnullになります。
そのままプロパティにアクセスすると「Cannot read properties of null」というエラーが発生し、スクリプトの実行が止まってしまいます。
// 存在しない可能性がある要素を安全に操作する
const modal = document.querySelector('.modal-window');
// ?. を使うことで、要素が存在する場合のみ classList.add が実行される
modal?.classList.add('is-active');
console.log('エラーを回避して実行を継続しました');
エラーを回避して実行を継続しました
この記法を用いることで、if文による存在チェックを簡潔に記述できるようになります。
NodeListの配列化と処理
querySelectorAllで取得したNodeListは、forEachメソッドを持っていますが、mapやfilterといった配列専用のメソッドは持っていません。
より高度な配列操作を行いたい場合は、スプレッド構文やArray.from()を使用して配列に変換するのが一般的です。
const allLinks = document.querySelectorAll('a');
// NodeListを本物の配列に変換する
const linkArray = [...allLinks];
// 配列メソッドのfilterを使用して、特定の条件のリンクだけ抽出する
const externalLinks = linkArray.filter(link => link.hostname !== window.location.hostname);
console.log(`外部リンクの数: ${externalLinks.length}`);
外部リンクの数: 5
パフォーマンスとメモリ管理の注意点
DOM操作はJavaScriptの処理の中でも比較的コストが高い(時間がかかる)作業の一つです。
そのため、不必要に要素取得を繰り返さないような工夫が求められます。
例えば、同じ要素を何度も使用する場合は、変数にキャッシュ(保存)しておくのが基本です。
// 悪い例:ループのたびにDOMを検索する
for (let i = 0; i < 100; i++) {
document.querySelector('#status').textContent = i;
}
// 良い例:一度取得した要素を再利用する
const statusEl = document.querySelector('#status');
for (let i = 0; i < 100; i++) {
statusEl.textContent = i;
}
また、大規模なアプリケーションで大量の要素を監視する場合は、要素を個別に取得してイベントを設定するのではなく、イベントデリゲーションという手法を検討してください。
これは親要素にイベントリスナーを1つだけ設置し、発生したイベントのターゲットを判別して処理を行う手法で、メモリ消費を抑える効果があります。
まとめ
JavaScriptで要素を取得する方法は多岐にわたりますが、基本的にはquerySelectorとquerySelectorAllを使いこなせれば、ほとんどのケースに対応可能です。
特定のIDに対してのみ高いパフォーマンスを求める場合にはgetElementByIdを利用し、状況に応じて適切なメソッドを選択しましょう。
また、取得した要素がnullである可能性を常に考慮し、オプショナルチェイニングなどを活用して堅牢なコードを書くことが大切です。
DOM要素の取得は全てのWeb開発の出発点ですので、今回紹介したテクニックを自身のプロジェクトに活かしてみてください。
