JavaScript | DOM 操作:DOM 基礎 – DOM API の基本概念

JavaScript JavaScript
スポンサーリンク

DOM API とは何か

DOM API は、ブラウザが作る「HTML の木構造(DOM ツリー)」を JavaScript から読み書きするための関数やプロパティ群です。document を起点にノード(要素・テキスト・コメント)を取得し、内容や属性を変更し、イベントを登録し、要素を作成・挿入・削除できます。ここが重要です:DOM は“画面そのもの”ではなく“設計図”。設計図(DOM)を変えると、ブラウザが画面を再描画します。


ノードとツリーの基本(document・要素・テキスト)

ツリーの構造を掴む

<h1 id="title">こんにちは</h1>
<p class="msg">DOM は木構造</p>
HTML
const title = document.querySelector("#title"); // 要素ノード
console.log(title.parentNode === document.body); // true(親)
console.log(title.firstChild.nodeType);          // 3(テキストノード)
JavaScript

DOM は親子・兄弟の関係を持つツリーです。要素の中の文字は「テキストノード」として別扱いになります。要素だけを辿るなら childrennextElementSibling、テキストも含めるなら childNodesnextSibling を使い分けます。


要素の取得とコレクション(静的とライブの違いを深掘り)

代表的な取得 API

document.getElementById("title");            // 速い・一意
document.querySelector(".msg");              // CSS セレクタで柔軟に1件
document.querySelectorAll(".msg");           // すべて(NodeList)
document.getElementsByClassName("msg");      // ライブな HTMLCollection
JavaScript

静的 NodeList と ライブ HTMLCollection

const staticList = document.querySelectorAll(".msg"); // 静的(後から増えても配列は固定)
const liveList = document.getElementsByClassName("msg"); // ライブ(DOM変化に同期)

const p = document.createElement("p");
p.className = "msg";
document.body.append(p);

console.log(staticList.length); // 元のまま
console.log(liveList.length);   // 1 増える(ライブ)
JavaScript

ここが重要です:処理の見通しが必要なら「静的」(querySelectorAll)、常に最新を反映したいなら「ライブ」(getElementsBy*)。ふだんは静的のほうがバグになりにくく扱いやすいです。


読み取り・更新の基本(textContent・innerHTML・属性・クラス)

テキストと HTML の違い

const el = document.querySelector("#title");
el.textContent = "<b>文字としてそのまま</b>"; // 安全(HTMLとしては解釈されない)
el.innerHTML = "<b>太字</b>";                   // HTMLとして展開(安全性に注意)
JavaScript

ここが重要です:外部データやユーザー入力は textContent が原則。innerHTML は信頼できる範囲に限定します(XSS対策)。

属性とプロパティ、classList と dataset

const btn = document.querySelector("#buy");
btn.setAttribute("aria-label", "購入"); // 属性の追加
btn.classList.add("is-active");         // クラス操作(CSS連携)
btn.dataset.sku = "SKU-123";            // data-* の読み書き(メタ情報)
JavaScript

ここが重要です:表示と振る舞いはクラス(classList)で切り替え、JS が読む設定値は data-* に置くと、HTML/CSS/JS の責務分離が保てます。


ノードの作成・挿入・削除(組み立ての正攻法)

生成→設定→挿入

const li = document.createElement("li"); // 要素を作る
li.textContent = "項目";                 // テキストを設定
document.querySelector("ul").append(li); // ツリーに追加
JavaScript

便利な挿入 API(位置を選べる)

const box = document.querySelector("#box");
box.prepend(document.createTextNode("先頭に追加"));
box.append(document.createTextNode("末尾に追加"));
box.before(document.createElement("hr"));  // 要素の前に
box.after(document.createElement("hr"));   // 要素の後に
JavaScript

置換・削除・大量追加

box.replaceWith(document.createElement("section")); // 置き換え
box.remove();                                       // 削除

const frag = document.createDocumentFragment();     // 大量追加はフラグメントで
for (let i = 0; i < 500; i++) {
  const li = document.createElement("li");
  li.textContent = `Item ${i}`;
  frag.append(li);
}
document.querySelector("ul").append(frag);
JavaScript

ここが重要です:生成→内容設定→まとめて挿入の順にすると、中途半端な描画を避け、再計算を減らせます。


イベントの基本(addEventListener と委譲)

要素に紐づける

document.addEventListener("DOMContentLoaded", () => {
  const btn = document.querySelector("#buy");
  btn.addEventListener("click", () => {
    btn.classList.toggle("is-active");
  });
});
JavaScript

親で受ける“イベント委譲”

const list = document.querySelector(".tabs");
list.addEventListener("click", (e) => {
  if (!(e.target instanceof HTMLButtonElement)) return;
  const tab = e.target.dataset.tab;
  document.querySelectorAll(".panel").forEach(p =>
    p.classList.toggle("is-hidden", p.id !== `panel-${tab}`)
  );
});
JavaScript

ここが重要です:イベントは JS に集約(HTMLの onclick は避ける)。委譲を使うと、後から追加される要素にも処理を適用でき、登録数を減らせます。


トラバーサルと検索の応用(closest・matches)

近い祖先を探す

const btn = document.querySelector(".buy-button");
const card = btn.closest(".product-card"); // もっとも近い祖先
JavaScript

セレクタ適合判定

if (btn.matches(".buy-button.is-active")) {
  // セレクタに合致するときの処理
}
JavaScript

ここが重要です:closest は「今いる場所から安全に上へ辿る」ための武器。HTML 構造変更に強いフックが書けます。


パフォーマンスと安全性の勘所(読み書きのバッチ化・XSS)

読み取りと書き込みはまとめる

// 悪い例:読み書きが交互でレイアウト計算が何度も走る
const el = document.querySelector("#box");
const w = el.offsetWidth;
el.style.width = (w + 10) + "px";
const h = el.offsetHeight;
el.style.height = (h + 10) + "px";

// 良い例:読み取りをまとめ、書き込みをまとめる
const el2 = document.querySelector("#box2");
const w2 = el2.offsetWidth;
const h2 = el2.offsetHeight;
el2.style.width = (w2 + 10) + "px";
el2.style.height = (h2 + 10) + "px";
JavaScript

安全な挿入の原則

  • 外部データ・ユーザー入力は textContent で入れる。
  • innerHTML は限定・検証済みのテンプレートだけ。
  • クラス切り替えで見た目を制御してロジックを単純化。

ここが重要です:DOM 操作は強力だが重く、危険にもなり得ます。再描画コストを意識し、XSS を防ぎ、責務分離を徹底すると規模が大きくなっても安定します。


まとめ

DOM API は「要素を見つける」「読んで書く」「作って挿入・削除」「イベントを結びつける」「ツリーを辿る」という5つの柱で成り立っています。静的/ライブのコレクションを使い分け、textContentclassList を基本に、安全・効率的に更新する。closest などの応用で構造変化に強くし、読み取り・書き込みをバッチ化して性能を守る。この感覚を体に入れれば、DOM は“意図通りに動く道具箱”になります。

タイトルとURLをコピーしました