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

JavaScript
スポンサーリンク
  1. insertBefore とは何か
  2. 基本の使い方(親・新ノード・参照ノードをそろえる)
    1. 末尾ではなく“任意の位置”に入れる
    2. 先頭に挿入する(最初の子の“前”に置く)
  3. 参照ノードが null のとき(末尾追加のショートカット)
    1. null を渡すと“末尾に挿入”
  4. 既存ノードの“移動”(複製ではないことに注意)
    1. 同じノードを挿し直すと“移動”になる
  5. 兄弟関係を使った“現在位置の近くに入れる”
    1. 特定要素の直前・直後へ入れる
  6. テキストノードと空白(firstChild が文字のことがある)
    1. 空白や改行も“ノード”として扱われる
  7. 便利な代替 API(before/after、append/prepend、insertAdjacent)
    1. 直感的に“前/後”へ置くなら before/after
    2. 親の“先頭/末尾”なら prepend/append
    3. HTML の近傍に差す insertAdjacentElement/HTML/Text
  8. DocumentFragment で大量挿入を軽くする
    1. まとめて作って“基準の前”へ一気に入れる
  9. 置き換え・差し替えの型(replaceChild / replaceChildren)
    1. 特定の子を“置き換える”
  10. よくあるエラーと回避策(親不一致・null・参照の選び方)
    1. 参照ノードが“その親の子でない”
    2. null を“意図せず”渡してしまう
  11. 実践例(並び替え、ヘッダ直前に挿入、広告ブロック差し替え)
    1. 並び替え:要素を上へ一段移動
    2. 見出しの直前に目次リンクを挿入
    3. プレースホルダの“前”に広告を差す(なければ末尾)
  12. まとめ

insertBefore とは何か

insertBefore は「親ノードの中で、指定した子ノードの“直前”に新しいノードを挿入する」メソッドです。形は parent.insertBefore(newNode, referenceNode)。ここが重要です:挿入先は必ず「親ノード」、基準になる referenceNode はその親の子でなければいけません。referenceNode の直前に newNode が入り、レイアウト上の順番が変わります。


基本の使い方(親・新ノード・参照ノードをそろえる)

末尾ではなく“任意の位置”に入れる

<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 x = document.createElement("li");
  x.textContent = "X";

  const ref = document.getElementById("b"); // これの“前”に挿入
  list.insertBefore(x, ref); // A, X, B, C の順になる
</script>
HTML

ここが重要です:参照ノード(ref)は「その親の子」である必要があります。違う親の子や null を渡すと意図通りに動きません(null は“末尾”扱いになる特例を除く)。

先頭に挿入する(最初の子の“前”に置く)

const list = document.getElementById("list");
const y = document.createElement("li");
y.textContent = "先頭";
list.insertBefore(y, list.firstChild); // 先頭に入る
JavaScript

ここが重要です:firstChild はテキストノードを含むことがあります。確実に要素の先頭に入れたいなら firstElementChild を参照するか、prepend を使うのも安全です。


参照ノードが null のとき(末尾追加のショートカット)

null を渡すと“末尾に挿入”

const list = document.getElementById("list");
const z = document.createElement("li");
z.textContent = "末尾";
list.insertBefore(z, null); // appendChild と同じ効果
JavaScript

ここが重要です:insertBefore は“前に入れる”メソッドですが、参照が null なら「末尾に入れる」特例があります。appendChild 相当として使えるため、位置によって一つのAPIに統一できます。


既存ノードの“移動”(複製ではないことに注意)

同じノードを挿し直すと“移動”になる

const list = document.getElementById("list");
const a = document.getElementById("a");
const c = document.getElementById("c");
list.insertBefore(a, c); // A を C の前へ“移動”(元の場所から消える)
JavaScript

ここが重要です:DOM ノードは唯一個体。同じノードを二箇所に同時配置することはできません。“複製したい”なら cloneNode(true) でコピーを作ってから挿入します。


兄弟関係を使った“現在位置の近くに入れる”

特定要素の直前・直後へ入れる

const item = document.getElementById("b");
const newEl = document.createElement("li");
newEl.textContent = "Bの前";

item.parentNode.insertBefore(newEl, item); // 親を辿って直前に
JavaScript

ここが重要です:親ノードが不明でも「基準要素の parentNode」で親を取り出し、その親に対して insertBefore すれば、直前へ確実に入れられます。直後に入れたい場合は item.nextSibling を参照して「その次の“前”」に入れるか、別のAPI(after)を使います。

const afterB = document.createElement("li");
afterB.textContent = "Bの後";
item.parentNode.insertBefore(afterB, item.nextSibling); // 直後に入る
JavaScript

テキストノードと空白(firstChild が文字のことがある)

空白や改行も“ノード”として扱われる

<ul id="list">
  <!-- 改行やインデントがあると firstChild がテキストノードの可能性 -->
  <li>A</li>
</ul>
<script>
  const list = document.getElementById("list");
  const el = document.createElement("li");
  el.textContent = "先頭に要素として";
  list.insertBefore(el, list.firstElementChild); // テキストではなく“要素”の前へ
</script>
HTML

ここが重要です:firstChild はテキストノードの可能性、firstElementChild は“要素”だけ。意図した位置に入れるため、どちらを基準にするか意識しましょう。


便利な代替 API(before/after、append/prepend、insertAdjacent)

直感的に“前/後”へ置くなら before/after

const b = document.getElementById("b");
const node = document.createElement("li");
node.textContent = "Bの前";
b.before(node); // 兄弟として“前”に挿入(親を意識しなくてよい)
JavaScript

ここが重要です:before/after は「基準要素の兄弟として置く」高レベルAPI。親を指定する必要がないため、読みやすいコードになります。

親の“先頭/末尾”なら prepend/append

const list = document.getElementById("list");
const n1 = document.createElement("li"); n1.textContent = "先頭";
const n2 = document.createElement("li"); n2.textContent = "末尾";
list.prepend(n1);
list.append(n2);
JavaScript

ここが重要です:位置が“頭か尻か”に限られるなら、insertBefore よりも直感的です。append は文字列も挿入できる点も便利。

HTML の近傍に差す insertAdjacentElement/HTML/Text

const ref = document.getElementById("b");
const el = document.createElement("li");
el.textContent = "Bの前";
ref.insertAdjacentElement("beforebegin", el); // ほかに afterbegin/beforeend/afterend
JavaScript

ここが重要です:“どこに入れるか”を語で指定できるため、テンプレート周りや部分更新に向きます。文字列を差すなら insertAdjacentHTML を使いますが、ユーザー入力は textContent を基本にして安全性を保ちます。


DocumentFragment で大量挿入を軽くする

まとめて作って“基準の前”へ一気に入れる

const ref = document.getElementById("b");
const frag = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
  const li = document.createElement("li");
  li.textContent = `行 ${i}`;
  frag.appendChild(li);
}
ref.parentNode.insertBefore(frag, ref); // B の前に 100 行まとめて入る
JavaScript

ここが重要です:1行ずつ insertBefore すると再計算が増えます。Fragment に集約して“1回の挿入”にすればパフォーマンスが大幅に改善します。


置き換え・差し替えの型(replaceChild / replaceChildren)

特定の子を“置き換える”

const list = document.getElementById("list");
const fresh = document.createElement("li");
fresh.textContent = "新しいB";
const old = document.getElementById("b");
list.replaceChild(fresh, old); // old を fresh に置換
JavaScript

ここが重要です:insertBefore は“挿入”専用。置き換えは replaceChild、全入れ替えは replaceChildren が簡単です。


よくあるエラーと回避策(親不一致・null・参照の選び方)

参照ノードが“その親の子でない”

const parent = document.getElementById("list");
const ref = document.getElementById("other"); // 別の親の子
const node = document.createElement("li");
parent.insertBefore(node, ref); // 例外:HierarchyRequestError(親子関係が不正)
JavaScript

ここが重要です:referenceNode は必ず parent の直下の子にする。わからない場合は「基準要素から親を辿る」形(ref.parentNode.insertBefore(…, ref))にすると安全です。

null を“意図せず”渡してしまう

参照が見つからず null になると、末尾挿入が発生します。ここが重要です:位置が重要な処理では、参照の存在を必ず確認し、見つからない場合の代替動作(追加しない、末尾に入れる、ログ出力など)を決めておきます。


実践例(並び替え、ヘッダ直前に挿入、広告ブロック差し替え)

並び替え:要素を上へ一段移動

function moveUp(el) {
  const prev = el.previousElementSibling;
  if (prev) el.parentNode.insertBefore(el, prev); // ひとつ前の“前”に自分を挿す→順序入れ替え
}
JavaScript

ここが重要です:自分自身を insertBefore すれば“移動”になる。シンプルな並び替えはこれで十分です。

見出しの直前に目次リンクを挿入

const h2 = document.querySelector("h2");
const nav = document.createElement("a");
nav.href = "#top";
nav.textContent = "ページ上部へ";
h2.parentNode.insertBefore(nav, h2); // h2 の直前に入る
JavaScript

ここが重要です:文書構造上の“特定位置”へ確実に差し込みたいとき、insertBefore は最短ルートです。

プレースホルダの“前”に広告を差す(なければ末尾)

const container = document.getElementById("feed");
const ad = document.createElement("div");
ad.className = "ad";
ad.textContent = "広告";
const placeholder = container.querySelector(".ad-placeholder");
container.insertBefore(ad, placeholder ?? null); // 参照がなければ末尾
JavaScript

ここが重要です:null を活用してフォールバックを作る。設置位置が柔軟になります。


まとめ

insertBefore は「親の中の特定の子の“直前”に挿入」するための基本メソッドです。親・新ノード・参照ノードの三点を正しく揃え、参照が null なら末尾に入る特性を理解する。同じノードを挿すと“移動”になるため、複製は cloneNode を使う。テキストノードの存在に注意し、firstElementChild を使う場面を見極める。位置によっては before/after/prepend/append/insertAdjacent を併用し、大量挿入は DocumentFragment でまとめる。これらを押さえれば、初心者でも“思った場所に正確に差す”ノード操作が書けます。

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