JavaScript DOM操作入門|querySelector・addEventListener・要素の追加と削除を完全解説
目次
DOMとは何か
DOM(Document Object Model)とは、HTMLドキュメントをJavaScriptから操作するためのインターフェースです。ブラウザはHTMLを読み込むと、その内容をツリー構造のオブジェクトとしてメモリ上に展開します。これがDOMです。
例えば以下のHTMLは、ブラウザ内部でこのようなツリー構造になります。
<html>
<body>
<h1 id="title">こんにちは</h1>
<ul id="list">
<li>アイテム1</li>
<li>アイテム2</li>
</ul>
</body>
</html>
document
└── html
└── body
├── h1 (id="title")
│ └── "こんにちは"(テキストノード)
└── ul (id="list")
├── li → "アイテム1"
└── li → "アイテム2"
JavaScriptからdocument.getElementById('title')などのメソッドを使うと、このツリーの特定のノードにアクセスして読み書きできます。
要素の取得方法
getElementById
IDで要素を1つ取得します。最もシンプルで高速です。
const title = document.getElementById('title');
console.log(title.textContent); // "こんにちは"
querySelector
CSSセレクターで要素を1つ取得します。ID・クラス・タグ・属性など、CSSで書けるセレクターが全て使えます。
const title = document.querySelector('#title'); // IDセレクター
const btn = document.querySelector('.btn-primary'); // クラスセレクター
const input = document.querySelector('input[type="text"]'); // 属性セレクター
const firstLi = document.querySelector('ul li'); // 子孫セレクター
複数マッチする場合は最初の1つだけが返ります。
querySelectorAll
条件に一致する全ての要素をNodeListとして取得します。
const items = document.querySelectorAll('#list li');
// NodeListはforEachで反復できる
items.forEach((item) => {
console.log(item.textContent);
});
// スプレッド演算子で配列に変換するとmapなども使える
const texts = [...items].map((item) => item.textContent);
イベントリスナー
addEventListener の基本
addEventListener(イベント名, コールバック関数)でイベントを登録します。
const button = document.querySelector('#submit-btn');
button.addEventListener('click', (event) => {
console.log('ボタンがクリックされました');
console.log(event.target); // イベントが発生した要素
});
よく使うイベント一覧
// クリック
element.addEventListener('click', handler);
// マウスオーバー・アウト
element.addEventListener('mouseenter', handler);
element.addEventListener('mouseleave', handler);
// テキスト入力(リアルタイム)
input.addEventListener('input', (e) => {
console.log(e.target.value); // 入力中の値
});
// フォームの送信
form.addEventListener('submit', (e) => {
e.preventDefault(); // デフォルトの送信動作をキャンセル
console.log('フォームが送信されました');
});
// DOMの読み込み完了後に処理を実行
document.addEventListener('DOMContentLoaded', () => {
console.log('DOMの準備ができました');
// ここでDOM操作を始める
});
DOMContentLoadedは、JavaScriptファイルをHTMLの<head>内に書く場合に特に重要です。これを使わないと、DOMが構築される前にJavaScriptが実行されて要素が見つからないエラーが発生します。
イベントの伝播(バブリング)
クリックイベントは内側から外側へ「バブリング」します。
document.querySelector('#parent').addEventListener('click', () => {
console.log('親がクリックされた');
});
document.querySelector('#child').addEventListener('click', (e) => {
console.log('子がクリックされた');
e.stopPropagation(); // 親へのバブリングを止める
});
要素の生成・追加・削除
createElement と appendChild
// li要素を作成してulに追加
const ul = document.querySelector('#list');
const newItem = document.createElement('li');
newItem.textContent = '新しいアイテム';
ul.appendChild(newItem); // ulの末尾に追加
insertAdjacentElement で挿入位置を指定
const referenceItem = document.querySelector('#list li:first-child');
const newItem = document.createElement('li');
newItem.textContent = '先頭に挿入';
// 挿入位置の指定
referenceItem.insertAdjacentElement('beforebegin', newItem); // 対象の前
referenceItem.insertAdjacentElement('afterbegin', newItem); // 対象内の先頭
referenceItem.insertAdjacentElement('beforeend', newItem); // 対象内の末尾
referenceItem.insertAdjacentElement('afterend', newItem); // 対象の後
remove で要素を削除
const item = document.querySelector('#list li:last-child');
item.remove(); // 要素をDOMから削除
属性の操作
classList でクラスを操作
const card = document.querySelector('.card');
card.classList.add('active'); // クラスを追加
card.classList.remove('hidden'); // クラスを削除
card.classList.toggle('open'); // クラスの追加/削除を切り替え
card.classList.contains('active'); // クラスが存在するか確認(真偽値)
style でインラインスタイルを操作
const box = document.querySelector('.box');
box.style.backgroundColor = '#3498db'; // background-color はキャメルケースで
box.style.fontSize = '18px';
box.style.display = 'none'; // 要素を非表示に
CSS管理の観点から、直接styleを変更するよりclassListでクラスを切り替える方が推奨されます。
dataset でデータ属性を操作
HTMLのdata-*属性をJavaScriptから読み書きします。
<button data-user-id="42" data-action="delete">削除</button>
const btn = document.querySelector('button');
console.log(btn.dataset.userId); // "42"(data-user-id → userId)
console.log(btn.dataset.action); // "delete"
btn.dataset.userId = '99'; // 値を書き換える
実践:TODOリストを作ってみる
これまでの知識を組み合わせて、シンプルなTODOリストを実装してみましょう。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>TODOリスト</title>
</head>
<body>
<h1>TODOリスト</h1>
<form id="todo-form">
<input type="text" id="todo-input" placeholder="タスクを入力" required>
<button type="submit">追加</button>
</form>
<ul id="todo-list"></ul>
<script src="app.js"></script>
</body>
</html>
// app.js
document.addEventListener('DOMContentLoaded', () => {
const form = document.querySelector('#todo-form');
const input = document.querySelector('#todo-input');
const list = document.querySelector('#todo-list');
// フォーム送信時にタスクを追加
form.addEventListener('submit', (e) => {
e.preventDefault();
const text = input.value.trim();
if (!text) return; // 空文字は無視
addTodoItem(text);
input.value = ''; // 入力欄をリセット
input.focus(); // フォーカスを戻す
});
function addTodoItem(text) {
const li = document.createElement('li');
// チェックボックス
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.addEventListener('change', () => {
li.style.textDecoration = checkbox.checked ? 'line-through' : 'none';
});
// テキスト
const span = document.createElement('span');
span.textContent = text;
// 削除ボタン
const deleteBtn = document.createElement('button');
deleteBtn.textContent = '削除';
deleteBtn.addEventListener('click', () => {
li.remove();
});
li.appendChild(checkbox);
li.appendChild(span);
li.appendChild(deleteBtn);
list.appendChild(li);
}
});
このコードはHTML・CSS・JavaScriptだけで動作します。ブラウザでHTMLファイルを開くだけで確認できるため、学習の第一歩として最適です。
改訂新版JavaScript本格入門
JavaScriptの基礎からDOM操作・非同期処理まで体系的に学べる定番書。現代のJavaScript(ES2022+)に対応した改訂版。
※ アフィリエイトリンクを含みます
まとめ
DOM操作の基本をまとめます。
- 要素の取得:
querySelector/querySelectorAllがCSSセレクターを使えて汎用的 - イベント:
addEventListenerでイベントを登録、e.preventDefault()でデフォルト動作をキャンセル - 要素の追加:
createElementで要素を作りappendChildで追加 - 要素の削除:
element.remove()で削除 - クラスの操作:
classList.add/remove/toggleを使う
DOM操作を覚えると、JavaScriptで動的なWebページを作れるようになります。まずはTODOリストを自力で実装してみることをおすすめします。