JavaScript で特定の HTML 要素にアクセスする最も基本的な方法が getElementById です。ページ内で一意な ID を指定して、その要素のテキスト変更、スタイル操作、イベント登録などを行います。
本記事では、getElementById の基本から、querySelector との違い、取得した要素の操作、null チェック、DOMContentLoaded との関係まで解説します。
・getElementById の基本構文と使い方
・querySelector(“#id”) との違いと使い分け
・取得した要素のテキスト変更(textContent / innerHTML)
・スタイル・属性・クラスの操作
・要素が見つからない場合の null チェック
・DOMContentLoaded で安全に要素を取得する方法
・フォーム値取得・モーダル操作の実務パターン
getElementById の基本
<h1 id="main-title">こんにちは</h1> <p id="description">説明文です。</p> <button id="submit-btn">送信</button>
// ID で要素を取得
const title = document.getElementById("main-title");
console.log(title); // <h1 id="main-title">こんにちは</h1>
console.log(title.textContent); // "こんにちは"
// ID が存在しない場合は null を返す
const notFound = document.getElementById("nonexistent");
console.log(notFound); // null
| ポイント | 内容 |
|---|---|
| 引数 | ID 文字列(# は不要) |
| 戻り値 | 見つかれば Element オブジェクト、見つからなければ null |
| 取得数 | 常に 1 要素(ID はページ内で一意のため) |
| 大文字小文字 | 区別する(”myId” と “myid” は別 ID) |
document.getElementById("#main-title") は動きません(null を返します)。# は CSS セレクタ構文であり、getElementById はID 名だけを渡します。# を使うのは querySelector の場合です。querySelector(“#id”) との比較
// querySelector: CSS セレクタ構文で # を付ける
const title = document.querySelector("#main-title");
console.log(title.textContent); // "こんにちは"
| 項目 | getElementById | querySelector |
|---|---|---|
| 構文 | getElementById(“myId”) | querySelector(“#myId”) |
| # の有無 | 不要 | 必要 |
| 速度 | わずかに速い(最適化されている) | 若干遅い(セレクタパーサーを経由) |
| 柔軟性 | ID のみ | CSS セレクタ全般(クラス / 属性 / 複合条件等) |
| 戻り値 | Element / null | Element / null |
・ID だけで取得する場合 →
getElementById(シンプルで最速)・ID + 子孫セレクタ(
#container .item)のような複合条件 → querySelector・チーム内で統一するなら querySelector に統一するのも合理的(CSS セレクタで全パターン対応)
取得した要素のテキストを変更する
const el = document.getElementById("description");
// textContent: テキストのみ取得・設定(HTML タグは無視)
el.textContent = "新しい説明文です。";
// innerHTML: HTML を含むコンテンツを取得・設定
el.innerHTML = "新しい<strong>説明文</strong>です。";
// innerText: 画面に表示されるテキストのみ(非表示要素は含まない)
console.log(el.innerText);
| プロパティ | 用途 | HTML の扱い |
|---|---|---|
| textContent | テキストの取得・設定(推奨) | HTML タグはエスケープされる(安全) |
| innerHTML | HTML を含むコンテンツの取得・設定 | HTML タグがそのまま解釈される(XSS リスク) |
| innerText | 画面表示テキストの取得 | CSS で非表示の要素は含まない |
el.innerHTML = userInput はユーザーが入力した <script> タグがそのまま実行されるXSS(クロスサイトスクリプティング)の危険があります。ユーザー入力の表示にはtextContent を使ってください。スタイルを操作する
const el = document.getElementById("main-title");
// インラインスタイルの変更
el.style.color = "red";
el.style.fontSize = "24px"; // CSS の font-size → camelCase
el.style.backgroundColor = "#f0f0f0";
el.style.display = "none"; // 非表示
el.style.display = ""; // 元に戻す(CSS の値に復帰)
// classList でクラスを切り替える方が推奨
el.classList.add("highlight");
el.classList.toggle("active");
el.style.color = "red" はインラインスタイルを追加するため、CSS の詳細度が上がって管理が難しくなります。CSS クラスで見た目を定義し、classList.add() / toggle() でクラスを切り替える方がメンテナブルです。属性を操作する
const link = document.getElementById("my-link");
// 属性の取得
const href = link.getAttribute("href");
console.log(href); // "https://example.com"
// 属性の設定
link.setAttribute("href", "https://new-url.com");
link.setAttribute("target", "_blank");
// 属性の削除
link.removeAttribute("target");
// 属性の存在チェック
if (link.hasAttribute("target")) {
console.log("target 属性がある");
}
// data-* 属性(dataset)
const card = document.getElementById("card-1");
console.log(card.dataset.userId); // data-user-id の値
card.dataset.status = "active"; // data-status を設定
null チェック: 要素が見つからない場合の対処
// 要素が存在しない場合は null → そのままプロパティにアクセスするとエラー
const el = document.getElementById("maybe-missing");
// NG: null.textContent → TypeError
// console.log(el.textContent);
// OK: null チェックしてからアクセス
if (el) {
console.log(el.textContent);
}
// オプショナルチェーニング(ES2020)
console.log(el?.textContent); // el が null なら undefined
ID のスペルミス、要素がまだ DOM に存在しない(スクリプトが head で実行された)等の理由で null が返ることがあります。null チェックなしでプロパティにアクセスすると
TypeError: Cannot read properties of null が発生します。DOMContentLoaded で安全に取得する
<!-- NG: head 内のスクリプトは body の要素を取得できない -->
<head>
<script>
const el = document.getElementById("title"); // null!
</script>
</head>
<body>
<h1 id="title">Hello</h1>
</body>
// DOM の読み込み完了後に実行
document.addEventListener("DOMContentLoaded", () => {
const el = document.getElementById("title");
console.log(el.textContent); // "Hello"
});
<body>
<h1 id="title">Hello</h1>
<!-- body の末尾なら全要素が読み込み済み -->
<script>
const el = document.getElementById("title");
console.log(el.textContent); // "Hello"
</script>
</body>
<!-- defer: HTML パース完了後にスクリプトを実行 --> <head> <script src="app.js" defer></script> </head> <body> <h1 id="title">Hello</h1> </body> <!-- app.js 内で getElementById は正常に動作する -->
| 方法 | 安全性 | 備考 |
|---|---|---|
| DOMContentLoaded イベント | 安全 | DOM 構築完了後に実行。画像の読み込みは待たない |
| body の末尾に script | 安全 | 最もシンプル |
| defer 属性 | 安全 | 推奨。HTML パース完了後に実行。head に書ける |
| head 内に script(対策なし) | 危険 | 要素がまだ存在せず null になる |
実務パターン集
パターン(1): フォームの入力値を取得
document.getElementById("submit-btn").addEventListener("click", () => {
const name = document.getElementById("name-input").value;
const email = document.getElementById("email-input").value;
console.log(`名前: ${name}, メール: ${email}`);
});
パターン(2): モーダルの表示/非表示
// モーダルを開く
document.getElementById("open-modal").addEventListener("click", () => {
document.getElementById("modal").classList.add("is-visible");
});
// モーダルを閉じる
document.getElementById("close-modal").addEventListener("click", () => {
document.getElementById("modal").classList.remove("is-visible");
});
パターン(3): カウンターの実装
let count = 0;
const display = document.getElementById("counter-display");
document.getElementById("increment").addEventListener("click", () => {
count++;
display.textContent = count;
});
document.getElementById("decrement").addEventListener("click", () => {
count--;
display.textContent = count;
});
パターン(4): 表示/非表示の切り替え(トグル)
document.getElementById("toggle-btn").addEventListener("click", () => {
const content = document.getElementById("toggle-content");
content.hidden = !content.hidden;
// hidden 属性: true で非表示、false で表示
});
パターン(5): ページ内リンクのスムーズスクロール
// ID で指定した要素までスムーズスクロール
function scrollToId(id) {
const el = document.getElementById(id);
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
}
よくある質問
getElementById が最もシンプルで高速です。クラス名・属性・複合セレクタなど多様な条件で検索する場合は querySelector に統一するのが合理的です。チーム内でルールを決めてください。getElementById は最初に見つかった要素だけを返し、他は無視されます。意図しない動作の原因になるため、ID の重複は避けてください。複数要素を操作する場合はクラス名を使ってください。textContent はテキストのみを安全に取得・設定します。innerHTML は HTML タグを含むコンテンツを扱えますが、ユーザー入力を直接設定すると XSS 脆弱性になります。通常は textContent を使い、HTML の挿入が必要な場合のみ innerHTML を使ってください。getElementById は document オブジェクトのメソッドであり、特定の要素から呼び出すことはできません(parentEl.getElementById はエラー)。要素内から検索するには parentEl.querySelector("#id") を使ってください。el.hidden = true は HTML の hidden 属性を設定し、display: none と同等に要素を非表示にします。el.style.display = "none" はインラインスタイルで非表示にします。hidden 属性の方がセマンティックで、JavaScript でのトグルも el.hidden = !el.hidden とシンプルに書けます。まとめ
ID による要素取得の要点をまとめます。
| やりたいこと | 方法 |
|---|---|
| ID で要素を取得 | document.getElementById(“myId”) ※ # 不要 |
| CSS セレクタで ID を取得 | document.querySelector(“#myId”) ※ # 必要 |
| テキストを変更 | el.textContent = “新しいテキスト” |
| HTML を変更 | el.innerHTML = “HTML コンテンツ”(XSS 注意) |
| スタイルを変更 | el.style.color = “red” / el.classList.add(“class”) |
| 属性を変更 | el.setAttribute(“href”, “url”) / el.dataset.key = “value” |
| 表示/非表示の切り替え | el.hidden = !el.hidden |
| null チェック | if (el) { … } / el?.textContent |
| DOM 読み込み後に実行 | DOMContentLoaded / defer 属性 |
クラス名での要素取得は「クラス名で要素を取得する方法」も併せて参照してください。

