JavaScriptでWebページを動かす|DOM操作の基本を実践で学ぶ
JavaScriptのDOM操作の基本を実践的なコード例で解説。要素の取得、変更、イベント処理など、Webページをインタラクティブにする方法を学べます。
editor

チョットデキルの編集部です。プログラミング学習に役立つ情報をお届けします。
HTMLとCSSで見た目を整えたWebページも、それだけでは「静的な文書」に過ぎません。ボタンを押したら表示が切り替わる、フォームに入力したらリアルタイムでバリデーションが走る。こうしたインタラクティブな動きを実現するのが、JavaScriptによるDOM操作です。この記事では、DOM操作の基本を実践的なコード例とともに解説します。JavaScriptとは?をまだ読んでいない方は、先にそちらで全体像を把握しておくと理解がスムーズです。
JavaScript の DOM 操作 とは
Web ページの HTML 構造 (DOM ツリー) を JavaScript から書き換えて、ボタン反応・要素追加・スタイル変更などの動きを付ける手法のことです。
document.querySelectorとaddEventListenerの 2 つでほぼ完結します。
TL;DR 早わかりサマリー
- DOM 操作は JavaScript で Web ページを動かす根幹で、フレームワーク (React/Vue) を理解する前提でもあります
- 覚えるべきは querySelector / addEventListener / textContent / classList / appendChild の 5 つだけ
- 1 週間で基本、1 ヶ月で実用、3 ヶ月で React に進むのが標準ペース
- 実用例を 3-5 個自分で書き切ると、フレームワークの理解が一気に楽になります
DOMとは何か
DOM(Document Object Model)は、ブラウザがHTMLを読み込んだ後に構築するツリー構造のデータです。HTMLの各要素がノード(節)としてツリーに配置され、JavaScriptからこのツリーにアクセスすることで、ページの内容や見た目をプログラムで操作できます。
たとえば以下のHTMLがあるとします。
HTML
<div id="app">
<h2>タスク一覧</h2>
<ul class="task-list">
<li>買い物</li>
<li>掃除</li>
</ul>
</div>ブラウザはこのHTMLを解析し、document オブジェクトを頂点とするツリーを作ります。JavaScriptは document を起点に、任意の要素を取得・変更・追加・削除できます。
要素を取得する:querySelector
DOM操作の第一歩は、操作したい要素を取得することです。現在最もよく使われるメソッドが querySelector と querySelectorAll です。
JavaScript
// IDで取得(1つだけ)
const app = document.querySelector('#app');
// クラス名で取得(最初の1つ)
const taskList = document.querySelector('.task-list');
// タグ名で取得(最初の1つ)
const heading = document.querySelector('h2');
// 複数要素を取得(NodeListが返る)
const items = document.querySelectorAll('.task-list li');querySelector はCSSセレクタをそのまま使えるため、HTMLとCSSの知識がそのまま活きます。HTML/CSSで初めてのWebサイトを作ろうで学んだセレクタの書き方が、ここでも役立ちます。
テキストや内容を変更する:textContent と innerHTML
要素を取得したら、その中身を書き換えられます。
JavaScript
const heading = document.querySelector('h2');
// テキストだけを書き換える
heading.textContent = '今日のタスク';
// HTMLごと書き換える
heading.innerHTML = '今日の<span style="color:#007A5A">タスク</span>';textContent は純粋なテキストとして扱うため、HTMLタグがそのまま文字列として表示されます。一方 innerHTML はHTMLとして解釈されるため、タグが反映されます。ユーザー入力を innerHTML で挿入するとセキュリティリスクがあるため、基本的には textContent を使い、HTMLの挿入が必要な場合のみ innerHTML を使うようにしましょう。
クラスを操作する:classList
見た目の切り替えは、CSSクラスの付け外しで行うのが定石です。classList を使えば、クラスの追加・削除・切り替えが簡単にできます。
JavaScript
const box = document.querySelector('.box');
// クラスを追加
box.classList.add('active');
// クラスを削除
box.classList.remove('active');
// あれば削除、なければ追加(トグル)
box.classList.toggle('active');
// クラスがあるか確認
if (box.classList.contains('active')) {
console.log('activeクラスが付いています');
}実践:トグルボタンを作る
classList.toggle を使った、よくあるUIパターンです。
HTML
<button id="toggle-btn">メニューを開く</button>
<nav id="menu" class="menu hidden">ナビゲーション内容</nav>CSS
.menu { padding: 16px; background: #f0f0f0; }
.hidden { display: none; }JavaScript
const btn = document.querySelector('#toggle-btn');
const menu = document.querySelector('#menu');
btn.addEventListener('click', () => {
menu.classList.toggle('hidden');
const isOpen = !menu.classList.contains('hidden');
btn.textContent = isOpen ? 'メニューを閉じる' : 'メニューを開く';
});ボタンを押すたびに hidden クラスが付いたり外れたりし、メニューの表示・非表示が切り替わります。
イベントを処理する:addEventListener
ユーザーの操作(クリック、入力、スクロールなど)に反応するには、addEventListener でイベントリスナーを登録します。
JavaScript
const button = document.querySelector('#my-button');
button.addEventListener('click', (event) => {
console.log('ボタンがクリックされました');
});よく使うイベントの種類は以下の通りです。
click: クリック時input: 入力内容が変化した時submit: フォーム送信時keydown: キーが押された時mouseover: マウスが要素に乗った時
実践:カウンターを作る
イベント処理と要素の更新を組み合わせた、シンプルなカウンターです。
HTML
<div>
<span id="count">0</span>
<button id="increment">+1</button>
<button id="decrement">-1</button>
<button id="reset">リセット</button>
</div>JavaScript
let count = 0;
const countDisplay = document.querySelector('#count');
function updateDisplay() {
countDisplay.textContent = count;
}
document.querySelector('#increment').addEventListener('click', () => {
count++;
updateDisplay();
});
document.querySelector('#decrement').addEventListener('click', () => {
count--;
updateDisplay();
});
document.querySelector('#reset').addEventListener('click', () => {
count = 0;
updateDisplay();
});変数 count で状態を管理し、ボタン操作のたびに表示を更新しています。小さな例ですが、「状態管理」と「UIへの反映」というフロントエンド開発の基本パターンが含まれています。
要素を作成・追加・削除する
JavaScriptでは、新しいHTML要素を動的に作成してページに追加できます。
JavaScript
// 新しいli要素を作成
const newItem = document.createElement('li');
newItem.textContent = '洗濯';
// 既存のリストに追加
const list = document.querySelector('.task-list');
list.appendChild(newItem);要素の削除は remove() メソッドで行います。
JavaScript
const item = document.querySelector('.task-list li:last-child');
item.remove();実践:フォームバリデーション
要素の作成・削除とイベント処理を組み合わせた、リアルタイムバリデーションの例です。
HTML
<form id="signup-form">
<label for="username">ユーザー名(3文字以上)</label>
<input type="text" id="username" />
<div id="username-error" style="color:red"></div>
<label for="email">メールアドレス</label>
<input type="email" id="email" />
<div id="email-error" style="color:red"></div>
<button type="submit">登録</button>
</form>JavaScript
const form = document.querySelector('#signup-form');
const usernameInput = document.querySelector('#username');
const emailInput = document.querySelector('#email');
const usernameError = document.querySelector('#username-error');
const emailError = document.querySelector('#email-error');
usernameInput.addEventListener('input', () => {
if (usernameInput.value.length < 3) {
usernameError.textContent = 'ユーザー名は3文字以上で入力してください';
} else {
usernameError.textContent = '';
}
});
emailInput.addEventListener('input', () => {
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailPattern.test(emailInput.value)) {
emailError.textContent = '有効なメールアドレスを入力してください';
} else {
emailError.textContent = '';
}
});
form.addEventListener('submit', (event) => {
event.preventDefault();
const isValid =
usernameInput.value.length >= 3 &&
/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(emailInput.value);
if (isValid) {
console.log('フォーム送信:', {
username: usernameInput.value,
email: emailInput.value,
});
}
});input イベントで入力のたびにチェックし、submit イベントで最終的なバリデーションを行っています。event.preventDefault() はフォームのデフォルト送信動作を止めるために必要です。
DOM操作で意識すべきポイント
実際の開発でDOM操作を行う際に、押さえておきたいポイントをまとめます。
パフォーマンス: DOMの更新はブラウザの再描画を伴うため、頻繁に行うと動作が重くなります。複数の変更をまとめて行う、documentFragment を使うなどの工夫が有効です。
セキュリティ: innerHTML にユーザー入力をそのまま挿入すると、XSS(クロスサイトスクリプティング)攻撃のリスクがあります。ユーザー入力には textContent を使いましょう。
イベント委譲: 動的に追加される要素にイベントを設定したい場合、親要素にリスナーを登録して子要素のイベントをキャッチする「イベント委譲」というテクニックが有効です。
JavaScript
// 個々のliではなく、親のulにリスナーを設定
document.querySelector('.task-list').addEventListener('click', (event) => {
if (event.target.tagName === 'LI') {
event.target.classList.toggle('done');
}
});この方法なら、後から追加された要素にも自動的にイベントが適用されます。
DOM操作からフレームワークへ
ここまで紹介した素のJavaScriptによるDOM操作は、Web開発の基礎中の基礎です。ReactやVueなどのフレームワークも、内部的にはDOM操作を行っています。フレームワークは「状態が変わったら自動的にDOMを更新する」仕組みを提供してくれますが、その裏側で何が起きているかを理解しているかどうかで、トラブル対応力に大きな差が出ます。
まずは素のJavaScriptでDOMを自在に操作できるようになることが、フロントエンド開発者としての確かな土台になります。
実用的な DOM 操作パターン 5 選
そのまま使える定番パターンです。
1. ボタンクリックで要素を表示 / 非表示
JavaScript
const btn = document.querySelector("#toggle-btn");
const panel = document.querySelector("#panel");
btn.addEventListener("click", () => {
panel.classList.toggle("hidden");
});2. フォーム入力をリアルタイム反映
JavaScript
const input = document.querySelector("#name-input");
const preview = document.querySelector("#preview");
input.addEventListener("input", (e) => {
preview.textContent = `こんにちは、${e.target.value}さん`;
});3. リストに項目を追加
JavaScript
const addBtn = document.querySelector("#add-btn");
const list = document.querySelector("#todo-list");
addBtn.addEventListener("click", () => {
const li = document.createElement("li");
li.textContent = "新しいタスク";
list.appendChild(li);
});4. クラスを切り替えてダークモード
JavaScript
const themeBtn = document.querySelector("#theme-btn");
themeBtn.addEventListener("click", () => {
document.body.classList.toggle("dark");
});5. API からデータ取得して表示
JavaScript
async function loadUsers() {
const res = await fetch("/api/users");
const users = await res.json();
const list = document.querySelector("#user-list");
for (const user of users) {
const li = document.createElement("li");
li.textContent = user.name;
list.appendChild(li);
}
}
loadUsers();これら 5 パターンを自分で書き切ると、ほとんどの動的 Web ページが作れるようになります。
フレームワーク (React) に進む前に押さえるべき DOM 知識
React に進んだとき、生 DOM の理解があると次のような部分で詰まりません。
1. リフロー / リペイントの理解 DOM 操作は重い処理です。React の仮想 DOM がなぜ存在するか、リアル DOM を意識せずに済む利点が体感できます。
2. イベントバブリング / キャプチャ click イベントが親要素まで伝播する仕組み。React の合成イベントを理解する前提知識です。
3. ライフサイクルの感覚 「要素が DOM に追加されたタイミングで何かしたい」「削除されるタイミングで cleanup したい」のような場面で、useEffect の意義が分かります。
4. パフォーマンス意識 1000 件のリストを描画する、ヘビーな計算を毎フレーム回す、などの場面で「なぜ重いか」が説明できる地力になります。
詳しくは React とは で次のステップを確認できます。
ハンズオン Step-by-Step
HTML ファイル 1 つで完結します。ブラウザで開いてボタンを押すと、内容が書き換わる体験ができます。
Step 1. 雛形 HTML を作る
dom-demo.html を作って次を貼ります。ボタンと表示用 div を用意します。
HTML
<!DOCTYPE html>
<html lang="ja">
<body>
<h1 id="title">DOM 操作デモ</h1>
<button id="btn">押すと変わる</button>
<div id="output"></div>
<script src="app.js"></script>
</body>
</html>Step 2. JS で要素を取得
app.js を作って、querySelector で要素を取得します。
JavaScript
const btn = document.querySelector("#btn");
const output = document.querySelector("#output");Step 3. クリックイベントを設定
ボタンクリックで output の中身を書き換えます。
JavaScript
btn.addEventListener("click", () => {
output.textContent = "クリックされました " + new Date().toLocaleTimeString();
});Step 4. スタイルも書き換え
クリックのたびに背景色が変わるようにしてみます。
JavaScript
btn.addEventListener("click", () => {
document.body.style.background =
"#" + Math.floor(Math.random() * 0xffffff).toString(16);
});Step 5. ブラウザで動作確認
dom-demo.html をブラウザで開き、ボタンを押すたびに表示と背景色が変わることを確認してください。
querySelector と addEventListener の 2 つだけで、DOM 操作の 8 割は表現できます。
関連リソース
- JavaScript とは
- React とは
- TypeScript vs JavaScript
- React vs Vue.js 徹底比較
- HTML/CSS で初めての Web サイトを作ろう
- JavaScript 入門コース
- 実践 JavaScript
よくある質問
Q. DOM 操作と React、どちらから学ぶべきですか
A. 必ず DOM 操作 (素の JavaScript) から学んでください。React は DOM 操作を抽象化した仕組みなので、土台が分かっていないと「なぜこう書くか」が理解できません。1 ヶ月程度で次のステップに進む前提で構いません。
Q. jQuery は今でも学ぶ価値がありますか
A. 既存プロジェクト保守のために知っておく価値はありますが、新規開発で採用する必要はもうありません。素の JavaScript + 必要に応じてフレームワークが現代のスタンダードです。
Q. TypeScript で書いた方がよいですか
A. 素の JavaScript で DOM 操作の基礎を理解してから、TypeScript に移行するのが効率的です。型エラーを読み解く力には JavaScript の基礎理解が必要だからです。詳しくは TypeScript vs JavaScript を参照してください。
Q. DOM 操作で一番つまづくポイントは
A. 「要素を取得してから動的に追加された要素にイベントが効かない」が定番のつまづきです。イベントバブリングを使った委譲 (event delegation) で解決できます。
Q. ブラウザ対応はどこまで考えるべきですか
A. 2026 年現在、Chrome / Safari / Firefox / Edge の最新版のみで実用十分です。IE11 のような古いブラウザはサポート不要です。caniuse.com で個別機能の対応状況を確認するのが定番です。
Q. 学んだ後の発展先は
A. React → Next.js が王道ルートです。Vue や Svelte も選択肢にあります。詳しくは React vs Vue 徹底比較 や Next.js とは を参照してください。
次のステップへ
DOM操作の基本を理解したら、実際にコードを書いて手を動かすことが上達への近道です。チョットデキルの「JS基礎」コースでは、変数やデータ型の基礎からDOM操作、非同期処理まで、段階的に学べるカリキュラムを用意しています。この記事で紹介したカウンターやバリデーションのような実践課題を通じて、確実にスキルを身につけていきましょう。
次に読むべきリソース
- 学習を始めたい方 — JavaScript 入門コース
- 深く理解したい方 — JavaScript とは?
- 無料相談したい方 — LuaGate 無料相談
出典・参考リンク
本記事の主張・数値・仕様に関する根拠は、以下の一次情報・公式ドキュメントを参照しています。リンク先の更新により内容が変わる場合があるため、最新情報は各公式サイトで確認してください。
- MDN Web Docs: Document Object Model (DOM)
- MDN Web Docs: JavaScript
- WHATWG DOM Standard
- ECMAScript 仕様 (ECMA-262)
- MDN Web Docs
- React 公式ドキュメント (react.dev)
この記事について
- 監修: 生田 陸人 (LuaGate エンジニア / 大手 IT 企業現役エンジニア)
- 公開: 2026-05-28
- 最終更新: 2026-05-28
- カテゴリ: フロントエンド
- 検証環境: Chrome 124 / Firefox 126 / Safari 17 / ECMAScript 2024
- 編集ポリシー: 公式ドキュメント・公的統計を一次情報として優先し、社内エンジニアが実機検証した内容のみを掲載しています。修正提案や事実誤認の指摘は チョットデキル運営 までお寄せください。