DOM とは何か
DOM(Document Object Model)は、ブラウザが「HTML や XML の文書をプログラムから操作できるようにした、木構造のデータモデル」です。ページは「ノード(要素、テキスト、コメントなど)」のツリーとして表現され、JavaScript はこの DOM ツリーにアクセスして、読み取り・変更・作成・削除ができます。ここが重要です:DOM は「画面そのもの」ではなく「画面の設計図(データ構造)」で、設計図を変えると画面が更新されます。
なぜ DOM が必要か(ブラウザと JavaScript の橋渡し)
ブラウザは HTML を読み込み、内部で DOM ツリーを作ります。JavaScript はこのツリーを操作することで、動的なページを実現します。ボタンを押したら表示を切り替える、フォームの入力内容を検証する、コンテンツを後から読み込む——いずれも DOM を通して行います。ここが重要です:JavaScript は「文字列の HTML」を直接いじるのではなく、DOM という「オブジェクト化された構造」を介して正確・安全に操作します。
基本構造をイメージする(ツリーとノード)
DOM は木構造で、document を根に html、head、body と要素が階層的につながり、各要素は属性(id、class など)やテキストノードを持ちます。
<!doctype html>
<html>
<head>
<title>DOM 入門</title>
</head>
<body>
<h1 id="title">こんにちは</h1>
<p class="msg">DOM は木構造です</p>
</body>
</html>
JavaScriptこのページは、JavaScript からは「ノードの集合」として扱えます。#title は要素ノード、こんにちは はテキストノード、id や class は属性として表現されます。
要素の取得(選択)と読み取りの基本
代表的な取得方法
// 単一要素の取得(CSS セレクタ)
const title = document.querySelector("#title");
// 複数要素の取得(NodeList)
const messages = document.querySelectorAll(".msg");
JavaScriptプロパティの読み取り
console.log(title.tagName); // "H1"(要素の種類)
console.log(title.id); // "title"(属性)
console.log(title.textContent); // "こんにちは"(テキスト)
JavaScriptここが重要です:querySelector は柔軟な CSS セレクタで「最初の一致」を、querySelectorAll は「すべての一致」を返します。古典的な getElementById や getElementsByClassName も高速ですが、柔軟性は CSS セレクタが上です。
内容やスタイルの変更(画面を書き換える)
テキストと属性を変える
const title = document.querySelector("#title");
title.textContent = "ようこそ";
title.setAttribute("data-role", "headline"); // 任意属性の追加
JavaScriptクラスを操作してスタイル適用
const msg = document.querySelector(".msg");
msg.classList.add("highlight"); // CSS: .highlight { color: red; }
msg.classList.remove("msg");
JavaScriptここが重要です:直接 style を書くより、クラス(classList)を切り替えて CSS に任せると「見た目の規則」を一箇所で管理でき、再利用性が高まります。
要素の作成・挿入・削除(DOM を組み立てる)
新しい要素を作る
const li = document.createElement("li");
li.textContent = "新しい項目";
JavaScriptツリーへ挿入・削除
const list = document.querySelector("ul");
list.appendChild(li); // 末尾に追加
// list.prepend(li); // 先頭に追加(モダンな方法)
li.remove(); // 削除(親から取り外す)
JavaScriptここが重要です:生成→内容設定→挿入の順にすると、途中の不完全な状態が画面に出にくく、意図が読みやすいコードになります。複数追加は「まとめてフラグメント化」すると効率的です(document.createDocumentFragment())。
イベントで動かす(ユーザー操作への反応)
クリックで内容を切り替える
const btn = document.querySelector("#toggle");
const panel = document.querySelector("#panel");
btn.addEventListener("click", () => {
const hidden = panel.classList.toggle("hidden");
btn.textContent = hidden ? "開く" : "閉じる";
});
JavaScriptここが重要です:イベントは「誰に」「何のイベントで」「何をするか」を明確に紐づけます。addEventListener を使うと、HTML と振る舞いを分離でき、保守性が上がります。
レイアウト・再描画とパフォーマンス(一歩深掘り)
DOM の読み取りと書き込みが交互に混ざると、ブラウザが何度もレイアウト・再描画を行い性能が落ちます。変更は「まとめて書く」、サイズ・位置の読み取り(例:offsetWidth)は「まとめて読む」のがコツです。また、頻繁な大量更新は仮想 DOM や requestAnimationFrame の利用、フラグメント挿入で負荷を下げます。ここが重要です:DOM は強力ですが「重い操作」でもあるため、更新をバッチ化し、スタイル変更はクラスで一括適用する設計が効きます。
よくある落とし穴(安全運用の感覚)
- 未存在要素の操作: 取得した要素が
nullの可能性を考え、存在チェックを行う。 - innerHTML の乱用: 文字列で HTML を差し込むと XSS リスクや壊れやすさが増します。必要なときだけ、信頼できる内容に限定して使う。
- イベントの多重登録: 同じ要素に何度も登録すると重複実行します。必要なら解除(
removeEventListener)、または一度だけ({ once: true })を使う。
ここが重要です:DOM 操作は「安全性(XSS)」「性能(reflow)」「可読性(関心の分離)」の三点を意識すると、規模が大きくなっても破綻しません。
まとめ
DOM は「HTML をブラウザ内でオブジェクト化した木構造」で、JavaScript がそれを操作して動的なページを作ります。要素の取得・内容/属性/クラスの変更・作成/挿入/削除・イベント登録が基本セットです。クラスでスタイル制御、変更のバッチ化、存在チェックと安全な挿入を徹底すると、実用的で壊れにくい UI を組み立てられます。DOM は“画面の設計図”。設計図を丁寧に扱えば、動きも見た目も思い通りにコントロールできます。

