- insertBefore とは何か
- 基本の使い方(親・新ノード・参照ノードをそろえる)
- 参照ノードが null のとき(末尾追加のショートカット)
- 既存ノードの“移動”(複製ではないことに注意)
- 兄弟関係を使った“現在位置の近くに入れる”
- テキストノードと空白(firstChild が文字のことがある)
- 便利な代替 API(before/after、append/prepend、insertAdjacent)
- DocumentFragment で大量挿入を軽くする
- 置き換え・差し替えの型(replaceChild / replaceChildren)
- よくあるエラーと回避策(親不一致・null・参照の選び方)
- 実践例(並び替え、ヘッダ直前に挿入、広告ブロック差し替え)
- まとめ
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 でまとめる。これらを押さえれば、初心者でも“思った場所に正確に差す”ノード操作が書けます。
