insertAdjacentHTML とは何か
insertAdjacentHTML は、指定した位置に「HTML文字列をそのままパースして挿入」するためのメソッドです。ターゲット要素の周囲や内側に、細かい位置を指定して差し込めます。ここが重要です:innerHTML のように“中身を丸ごと置き換えず”、部分的にHTMLを追加できるため、既存の構造やイベントを壊しにくいのが利点です。ただし、外部データをそのまま渡すとHTMLインジェクションの危険があるので、取り扱いは慎重に。
位置指定の4種類(どこに挿入されるか)
beforebegin(要素の直前)
ターゲット要素の外側で、直前の兄弟として挿入されます。
<div id="card">内容</div>
<script>
const card = document.getElementById("card");
card.insertAdjacentHTML("beforebegin", "<p>前に挿入</p>");
</script>
HTMLafterbegin(要素の先頭)
ターゲット要素の内側で、最初の子として挿入されます。
card.insertAdjacentHTML("afterbegin", "<strong>先頭に追加</strong>");
JavaScriptbeforeend(要素の末尾)
ターゲット要素の内側で、最後の子として挿入されます(append と同じ場所)。
card.insertAdjacentHTML("beforeend", "<em>末尾に追加</em>");
JavaScriptafterend(要素の直後)
ターゲット要素の外側で、直後の兄弟として挿入されます。
card.insertAdjacentHTML("afterend", "<p>後に挿入</p>");
JavaScriptここが重要です:内側に入れるのは afterbegin / beforeend、外側に置くのは beforebegin / afterend。目的に合わせて正確な位置を選ぶと、最小限の差分更新ができます。
innerHTML・DOM操作との使い分け(壊さず速く)
innerHTML との違い
innerHTML は“中身を丸ごと置き換える”ため、既存の子要素が破棄され、紐付けたイベントも消えます。insertAdjacentHTML は“差し込むだけ”なので、既存部分には触れません。ここが重要です:部分更新は insertAdjacentHTML、全置換は innerHTML。ただし、外部データの直接挿入は常に危険という前提を忘れないこと。
DOM API(createElement / append)との違い
DOM API は「要素をコードで組み立てる」ので安全ですが、記述がやや冗長。insertAdjacentHTML は「小さなテンプレート」を一気に差し込めます。ここが重要です:安全性重視や複雑な構造は DOM API、軽微な定型HTMLの差し込みは insertAdjacentHTML、と役割分担すると保守しやすいです。
安全性の深掘り(HTMLインジェクション対策が最優先)
外部データ(ユーザー入力・URLパラメータ・外部API)をそのまま文字列に混ぜて渡すと、タグやイベント属性が“実行される”余地が生まれます。必ずエスケープするか、文字は textContent(または insertAdjacentText)で挿入します。
function escapeHTML(s) {
return String(s).replace(/[&<>"']/g, c => ({'&':'&','<':'<','>':'>','"':'"',"'":'''})[c]);
}
const user = '<img src=x onerror=alert(1)>';
card.insertAdjacentHTML("beforeend",
`<p>ようこそ、<strong>${escapeHTML(user)}</strong> さん</p>`
); // 動的部分は必ずエスケープ
JavaScriptここが重要です:構造(p, strong など)は固定テンプレートにし、動的部分は“文字だけ”をエスケープして埋めるのが鉄則。完全に安全にしたいなら、構造は DOM API、文字は textContent を使うのが最も堅実です。
実践パターン(局所差し込み・イベント維持・バッチ化)
局所的な通知を先頭に差し込む
<div id="notice"></div>
<script>
const box = document.getElementById("notice");
box.insertAdjacentHTML("afterbegin", '<div class="alert">保存しました</div>');
</script>
HTML既存の子要素やイベントは壊さず、先頭に新しい要素が追加されます。ここが重要です:差し込み位置を正確に選べば、最小限の更新で済み、予期せぬ副作用を避けられます。
既存イベントを保ったまま末尾に追加する
<div id="list"></div>
<button id="add">追加</button>
<script>
const list = document.getElementById("list");
const add = document.getElementById("add");
add.addEventListener("click", () => {
// 末尾にカードを追加(既存のイベントはそのまま)
list.insertAdjacentHTML("beforeend",
'<div class="card"><h3>新規</h3><button class="do">実行</button></div>'
);
});
// 親でイベント委譲(後から追加される要素にも効く)
list.addEventListener("click", (e) => {
const t = e.target;
if (t instanceof Element && t.matches(".do")) {
t.textContent = "完了";
}
});
</script>
HTMLここが重要です:親にイベントを置く“委譲”と組み合わせると、後から差し込んだ要素にも自動で処理が効き、イベント張り直しが不要になります。
大量挿入は文字列連結より段階的に
巨大なHTMLを一気に差し込むと、パースと再描画のコストが高くなります。小さな塊に分けるか、可能なら DocumentFragment+DOM APIでの組み立てに切り替えると体感が軽くなります。ここが重要です:読み取りと書き込みをバッチ化し、挿入回数を減らす設計が性能のカギです。
補助メソッドとの使い分け(insertAdjacentText・insertAdjacentElement)
文字だけなら insertAdjacentText
HTMLとしてではなく“文字”を挿入します(安全)。
card.insertAdjacentText("beforeend", "純粋な文字の追記");
JavaScript既存ノードを挿入するなら insertAdjacentElement
事前に createElement した要素を、その位置へ差し込みます(安全・柔軟)。
const btn = document.createElement("button");
btn.textContent = "OK";
card.insertAdjacentElement("afterbegin", btn);
JavaScriptここが重要です:動的データは文字で、構造は要素で。HTML文字列を使うのは“固定テンプレートを小さく差し込む”場合に限ると覚えておくと、事故が激減します。
まとめ
insertAdjacentHTML は、ターゲット周辺の4つの位置に“部分的にHTMLを差し込める”便利なメソッドです。innerHTML と違い既存の中身を壊さずに更新でき、イベントも維持しやすい一方、外部データの混入はHTMLインジェクションの危険を伴います。構造はテンプレート(またはDOM API)で固定、動的部分は必ずエスケープし、必要に応じて insertAdjacentText/Element を使い分ける。位置指定を正確に選び、イベント委譲とバッチ化で性能と保守性を両立する——この指針を守れば、初心者でも安全で意図通りの部分更新が書けます。
