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

JavaScript
スポンサーリンク

replaceChild とは何か

replaceChild は「親ノードの子を別のノードに置き換える」メソッドです。形は parent.replaceChild(newChild, oldChild)。oldChild は親から外れ、newChild がその位置に入ります。ここが重要です:oldChild は“親の直下の子”である必要があり、newChild は DOM ノード(要素やテキスト)でなければいけません。置き換えは“挿入+削除”を一度に安全に行う手段です。


基本の使い方(親・新ノード・旧ノードの三点をそろえる)

子要素を別の要素に置き換える

<ul id="list">
  <li id="a">A</li>
  <li id="b">B</li>
  <li id="c">C</li>
</ul>
<script>
  const list = document.getElementById("list");
  const old = document.getElementById("b");       // 置き換え対象(親の直下の子)
  const fresh = document.createElement("li");     
  fresh.textContent = "B(新しい要素)";

  const removed = list.replaceChild(fresh, old);  // B → 新しい要素に置換
  console.log(removed.id); // "b"(返り値は取り外されたノード)
</script>
HTML

ここが重要です:返り値として“外された oldChild”が返ります。必要なら別の場所へ再配置できます(移動扱い)。

テキストノードを置き換える

const title = document.getElementById("title");
// 先頭の子がテキストノードなら、それを別ノードに置き換え
const strong = document.createElement("strong");
strong.textContent = "重要な見出し";
title.replaceChild(strong, title.firstChild);
JavaScript

ここが重要です:空白や改行も“テキストノード”。何を置き換えているかを firstChild(テキストも含む)か firstElementChild(要素のみ)で見分けると、意図通りに動きます。


置き換え時の“移動”と“複製”(cloneNode の使い分け)

newChild は“移動”される(複製されない)

const x = document.getElementById("x");    // 既存ノード
const container = document.getElementById("container");
const target = document.getElementById("slot");
container.replaceChild(x, target);         // x が“移動”して slot を置換
// 元の場所から x は消える(DOM ノードは唯一個体)
JavaScript

ここが重要です:同じノードを二箇所に同時配置はできません。“元の場所も残したい”なら複製してから置換します。

const copy = x.cloneNode(true);            // 子要素まで深い複製
container.replaceChild(copy, target);      // 複製で置換 → 元の x はそのまま
JavaScript

よくあるエラーと安全なガード(親不一致・存在チェック)

oldChild が親の直下の子でない

const parent = document.getElementById("list");
const otherChild = document.getElementById("other"); // 別の親の子
const fresh = document.createElement("li");
parent.replaceChild(fresh, otherChild); // 例外:HierarchyRequestError
JavaScript

ここが重要です:置き換える前に「oldChild.parentNode === parent」を確認します。存在しない可能性にも備えて null ガードを入れると堅牢です。

function safeReplace(parent, fresh, old) {
  if (old && old.parentNode === parent) parent.replaceChild(fresh, old);
}
JavaScript

まとめて差し替える場合の選択肢(replaceChildren・textContent)

子を一括リセットしてから新要素を入れる

const box = document.getElementById("box");
const fresh = document.createElement("p");
fresh.textContent = "新しい内容";
box.replaceChildren(fresh); // 全クリア→まとめて追加(高速で簡潔)
JavaScript

ここが重要です:多数の子を個別に replaceChild するより、replaceChildren で“一撃入れ替え”のほうが読みやすく高速なことが多いです。テキストだけなら textContent = “” でクリアしてから append。


近傍への差し込みと置換の代替(replaceWith・insertAdjacent)

要素自身を“自分で”置き換える

const old = document.getElementById("b");
const fresh = document.createElement("li");
fresh.textContent = "新しいB";
old.replaceWith(fresh); // 親を意識せず old を fresh に置換(モダンAPI)
JavaScript

ここが重要です:replaceWith は“基準要素自身”を置き換える高レベルAPI。読みやすさ重視ならこちらも有力です。

HTML 近傍へ差し込む

const old = document.getElementById("b");
old.insertAdjacentElement("beforebegin", fresh);
old.remove();
JavaScript

ここが重要です:「どこに入れるか」を語で指定できる insertAdjacent 系は、テンプレート断片の差し替えに便利です。


イベント・参照・クリーンアップ(後片付けの注意点)

取り外したノードのイベントは“ノードに残る”

replaceChild は oldChild を取り外すだけで、付与済みのイベントリスナーはノードに紐づいたままです。再配置すればそのまま動きます。ここが重要です:完全に破棄したい場合は、外部で保持している参照(変数や配列)を null にする、タイマー・Observer を停止するなど、メモリリーク対策を徹底します。

一時URLやメディアの解放

Object URL(URL.createObjectURL)を差し替えで不要にしたら URL.revokeObjectURL を呼び、リソースを解放します。ここが重要です:リソース系は“明示的な後片付け”が必要になることがあります。


実践例(カード差し替え、行のインライン編集、プレビュー更新)

リストの特定行を丸ごと差し替える

function replaceRow(id, text) {
  const old = document.getElementById(id);
  if (!old) return;
  const fresh = document.createElement("li");
  fresh.id = id;
  fresh.textContent = text;
  old.parentNode.replaceChild(fresh, old);
}
replaceRow("b", "B(更新済み)");
JavaScript

ここが重要です:IDを維持したまま中身ごと入れ替えると、参照の整合が保てます。

インライン編集の確定で表示用ノードに置換

function commitEdit(inputEl) {
  const parent = inputEl.parentNode;
  const view = document.createElement("span");
  view.textContent = inputEl.value.trim();
  parent.replaceChild(view, inputEl);
}
JavaScript

ここが重要です:編集用 input を表示用要素に置き換えるだけで、自然な編集フローが作れます。

画像プレビューの差し替え(失敗時フォールバック)

const img = document.getElementById("preview");
function setPreview(blob) {
  const url = URL.createObjectURL(blob);
  const fresh = document.createElement("img");
  fresh.alt = "プレビュー";
  fresh.onload = () => URL.revokeObjectURL(url);
  fresh.onerror = () => { fresh.src = "/img/fallback.png"; };
  fresh.src = url;
  img.parentNode.replaceChild(fresh, img);
}
JavaScript

ここが重要です:置き換え前にイベントを設定し、成功・失敗・解放までを一つの流れにしておくと安定します。


まとめ

replaceChild は「親の直下の特定の子を、新ノードに一発置換」するための基本メソッドです。親・oldChild の整合を必ず確認し、newChild は“移動”になることを理解して、複製が必要なら cloneNode を使う。多数の差し替えは replaceChildren で一括、要素自身の置換は replaceWith も有効。イベントと参照はノードに残るため、後片付け(参照破棄・リソース解放)まで含めて設計する。これらを押さえれば、初心者でも安全で意図通りの“置換”操作が書けます。

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