JavaScript | DOM 操作:ノード操作 – appendChild

JavaScript
スポンサーリンク

appendChild とは何か

appendChild は、親ノードの「末尾」に子ノードを追加するメソッドです。DOM で新しく作った要素(createElement)や既存の要素を、指定した親の最後に差し込みます。ここが重要です:appendChild は“必ず末尾”に追加し、同じノードをもう一度追加すると「複製」ではなく「移動」になります(DOM ノードは唯一個体)。


基本の使い方(作成 → 設定 → 追加の流れ)

要素を作って末尾に追加する

const card = document.createElement("div");
card.className = "card";
card.textContent = "こんにちは!";

// body の末尾に追加
document.body.appendChild(card);
JavaScript

ここが重要です:createElement 直後の要素は画面にありません。属性・テキスト・イベントを設定してから appendChild すると、期待通りの状態で表示されます。

子要素を入れ子にしてからまとめて追加

const article = document.createElement("article");
const h3 = document.createElement("h3");
h3.textContent = "タイトル";
const p = document.createElement("p");
p.textContent = "本文";

article.appendChild(h3);
article.appendChild(p);
document.getElementById("root").appendChild(article);
JavaScript

ここが重要です:入れ子構造は“親を先に作り、子を順に appendChild”が定石。読む順と同じでわかりやすい。


appendChild と append の違い(どちらを使うかの判断)

appendChild は「ノード専用」、append は「文字列もOK」

const box = document.getElementById("box");
const span = document.createElement("span");
span.textContent = "世界";

box.appendChild(span);     // Node を追加
box.append("こんにちは");  // 文字列も追加できる(appendChild では不可)
JavaScript

ここが重要です:文字列も足したいなら append、Node だけなら appendChild。どちらも「末尾に追加」ですが、append は複数引数も渡せます。


既存ノードの移動と重複(“同じものは2回置けない”)

2回目の appendChild は“複製”ではなく“移動”

const item = document.createElement("div");
item.textContent = "A";

const left = document.getElementById("left");
const right = document.getElementById("right");

left.appendChild(item);   // left の末尾へ
right.appendChild(item);  // right の末尾へ“移動”する(left からは消える)
JavaScript

ここが重要です:同じノードを複数箇所に同時配置したいなら、cloneNode(true) で複製を作ってから追加します。

const copy = item.cloneNode(true);
left.appendChild(copy);
JavaScript

テキストノードの扱い(textContent が基本)

テキストノードを直接追加することもできる

const t = document.createTextNode("こんにちは!");
document.getElementById("box").appendChild(t);
JavaScript

ここが重要です:通常は element.textContent = “…” が簡潔で安全。createTextNode は細かい制御をしたいときだけ使います(いずれも HTML を実行せず“文字”として扱うため安全)。


挿入位置の応用(前後に入れたいときは別メソッド)

末尾以外に入れるには before/after/prepend

const li = document.createElement("li");
li.textContent = "先頭へ";

const list = document.getElementById("list");
list.prepend(li);        // 先頭
// list.appendChild(li); // 末尾
// list.firstElementChild.before(li); // 先頭要素の“前”
JavaScript

ここが重要です:appendChild は末尾限定。位置を柔軟に制御するなら prepend/before/after を使うと直感的。


パフォーマンス最適化(大量追加はフラグメントで)

DocumentFragment にまとめて作って一括挿入

const frag = document.createDocumentFragment();
for (let i = 0; i < 500; i++) {
  const row = document.createElement("div");
  row.className = "row";
  row.textContent = `行 ${i}`;
  frag.appendChild(row);
}
document.getElementById("table").appendChild(frag);
JavaScript

ここが重要です:1件ずつDOMへ追加するとレイアウト再計算が多く発生。フラグメントで“まとめて作り、まとめて挿入”すると一気に軽くなります。


置き換え・削除・クリア(差し替えの型を覚える)

子を入れ替える・全クリアして差し込む

const container = document.getElementById("container");
const fresh = document.createElement("div");
fresh.textContent = "新しい内容";

// すべての子を消してから入れる
container.replaceChildren(fresh);
JavaScript

要素を消す

const card = document.getElementById("card");
card.remove(); // 親から切り離される
JavaScript

ここが重要です:replaceChildren は「まとめてクリア→まとめて追加」を一撃で行う便利メソッド。appendChild だけでは“追加”しかできないため、差し替えは別APIを使うのが楽です。


セキュリティの基本(innerHTML より textContent)

ユーザー入力は“文字”として差し込む

function addMessage(parent, userText) {
  const p = document.createElement("p");
  p.textContent = userText; // 安全
  parent.appendChild(p);
}
JavaScript

ここが重要です:innerHTML に外部入力を渡すと XSS の危険が出ます。createElement + textContent の組み合わせなら“常に文字扱い”で安全。


実践例(トースト通知、ボタン追加、動的リスト)

トースト通知を生成して自動消去

function toast(text, kind = "info") {
  const t = document.createElement("div");
  t.className = `toast toast-${kind}`;
  t.textContent = text;
  document.body.appendChild(t);
  setTimeout(() => t.remove(), 2000);
}
toast("保存しました", "success");
JavaScript

ここが重要です:作る→設定→appendChild→タイマーで remove の型を身につけると、使い捨て UI がすぐ書けます。

送信ボタンを動的に追加して状態制御

const form = document.getElementById("form");
const btn = document.createElement("button");
btn.type = "button";
btn.textContent = "送信";
btn.addEventListener("click", async () => {
  btn.disabled = true;
  btn.textContent = "送信中…";
  try { await new Promise(r => setTimeout(r, 800)); }
  finally { btn.disabled = false; btn.textContent = "送信"; }
});
form.appendChild(btn);
JavaScript

ここが重要です:視覚(文言)と操作不可(disabled)を同じロジックで切り替え、状態のズレをなくす。

リストに項目を末尾追加

const list = document.getElementById("todo");
function addItem(text) {
  const li = document.createElement("li");
  li.textContent = text;
  list.appendChild(li);
}
addItem("牛乳を買う");
addItem("メール返信");
JavaScript

ここが重要です:末尾追加は appendChild が最短でわかりやすい。先頭追加・任意位置は prepend/before/after と使い分けます。


よくある落とし穴と対策

作っただけでは表示されないため、必ず親へ appendChild する。大量追加はフラグメントでまとめる。同じノードを二重に置くと“移動”になるので、複製は cloneNode を使う。外部入力は textContent で差し込み、innerHTML 乱用を避ける。ここが重要です:位置制御(末尾限定)、唯一性(移動になる)、性能(まとめて挿入)、安全(文字扱い)の四点を押さえれば、appendChild は“確実に効く”基本ツールになります。


まとめ

appendChild は「親の末尾に子ノードを追加する」メソッドです。作成→設定→追加の順で使い、文字は textContent、複数や大量は DocumentFragment、位置のバリエーションは prepend/before/after、複製は cloneNode を併用。安全性とパフォーマンス、唯一性の特性を理解すれば、初心者でも直感的に動的 UI を構築できます。

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