✅ replaceChild() – replace a child element by a new element.
🔹 What is replaceChild()?
replaceChild()is a DOM method used to replace an existing child node with a new node.It works on the parent node.
✏️ Syntax
parentNode.replaceChild(newChild, oldChild);💊 Parameters
newChild→ The new node that will replace the old oneoldChild→ The existing child node to be replaced
👉 Key Points
Replaces only child nodes of a parent
The position of the old node remains the same
Returns: the replaced (old) node
Throws an error if
oldChildis not a child ofparentNode
1️⃣ Replace an element example
✏️ HTML
<ul id="menu">
<li>Homepage</li>
<li>Services</li>
<li>About</li>
<li>Contact</li>
</ul>🧠 JavaScript
const menu = document.getElementById('menu');
// create a new <li>
const li = document.createElement('li');
li.textContent = 'Home';
// replace the first list item
menu.replaceChild(li, menu.firstElementChild);<ul id="menu">
<li>Home</li>
<li>Services</li>
<li>About</li>
<li>Contact</li>
</ul>📌 The first <li> (Homepage) is replaced with Home.
🧠 How it works
Select the parent element (
ul)Create a new element (
li)Replace the old child using
replaceChild()
🔁 Modern Alternative
// select the element to be replaced
const firstItem = document.querySelector('#menu li');
// create a new element
const newLi = document.createElement('li');
newLi.textContent = 'Home';
// replace the old element
firstItem.replaceWith(newLi);✔️ Simpler
✔️ No parent reference needed
<div class="infographic-replaceel">
<style>
.infographic-replaceel {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--good: #1a8a5f;
--good-soft: #e1f2ea;
--bad: #c8452e;
--bad-soft: #f7e3df;
box-sizing: border-box;
max-width: 880px;
margin: 0 auto;
font-family: 'Inter', system-ui, sans-serif;
color: var(--ink);
background: var(--paper);
overflow-x: hidden;
}
.infographic-replaceel[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--good: #4fbf8f;
--good-soft: #16281f;
--bad: #e0715a;
--bad-soft: #2e211d;
}
.infographic-replaceel * { box-sizing: border-box; }
.infographic-replaceel h1 { font-family: 'Fraunces', Georgia, serif; font-weight: 600; margin: 0; }
.infographic-replaceel p { margin: 0; }
.infographic-replaceel button { font-family: inherit; }
.rp-wrap { padding: clamp(1.25rem, 5vw, 2.5rem) clamp(1.1rem, 5vw, 3rem) 2rem; }
.rp-hero { text-align: center; margin-bottom: 1.2rem; }
.rp-hero h1 { font-size: clamp(1.35rem, 4.5vw, 1.85rem); }
.rp-hero p { color: var(--ink-soft); margin-top: 0.4rem; font-size: 0.84rem; }
.rp-tabs { display: flex; flex-wrap: wrap; gap: 0.4rem; justify-content: center; margin-bottom: 1.2rem; }
.rp-tab { border: 1px solid var(--line); background: var(--paper-alt); color: var(--ink-soft); padding: 0.36rem 0.65rem; font-size: 0.66rem; font-weight: 700; cursor: pointer; font-family: 'IBM Plex Mono', monospace; }
.rp-tab.is-active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
.rp-tab:hover:not(.is-active) { border-color: var(--ink-soft); color: var(--ink); }
.rp-panel { display: none; }
.rp-panel.is-active { display: block; }
.rp-code { background: #1e1e1e; color: #d4d4d4; border-radius: 5px; padding: 0.6rem 0.8rem; font-family: 'IBM Plex Mono', monospace; font-size: 0.66rem; line-height: 1.6; margin-bottom: 1rem; white-space: pre; overflow-x: auto; }
.tok-kw { color: #569cd6; }
.tok-fn { color: #dcdcaa; }
.tok-str { color: #ce9178; }
.tok-var { color: #9cdcfe; }
.tok-punc { color: #d4d4d4; }
.tok-com { color: #6a9955; }
.rp-page { border: 1.5px solid var(--line); background: var(--paper-alt); border-radius: 6px; overflow: hidden; margin-bottom: 1rem; }
.rp-page-bar { background: #2b2b2b; padding: 0.4rem 0.6rem; display: flex; gap: 0.3rem; }
.rp-page-dot { width: 8px; height: 8px; border-radius: 50%; background: #555; }
.rp-page-body { padding: 0.9rem 1rem; background: var(--paper); }
.rp-slot { position: relative; height: 2.1em; margin-bottom: 0.3rem; }
.rp-item { position: absolute; inset: 0; border: 1.5px solid var(--line); border-radius: 4px; padding: 0.32rem 0.55rem; font-size: 0.8rem; display: flex; align-items: center; transition: opacity 0.4s ease, transform 0.4s ease, border-color 0.4s ease, background 0.4s ease; }
.rp-item.old { opacity: 1; }
.rp-item.old.is-out { opacity: 0; transform: scale(0.9); border-color: var(--bad); background: var(--bad-soft); color: var(--bad); text-decoration: line-through; }
.rp-item.new { opacity: 0; transform: translateY(6px) scale(0.95); }
.rp-item.new.is-in { opacity: 1; transform: translateY(0) scale(1); border-color: var(--good); background: var(--good-soft); }
.rp-static { border: 1.5px solid var(--line); border-radius: 4px; padding: 0.32rem 0.55rem; font-size: 0.8rem; margin-bottom: 0.3rem; }
.rp-play { display: block; margin: 0 auto; border: none; background: var(--accent); color: #fff; padding: 0.5rem 1.2rem; font-size: 0.8rem; font-weight: 600; cursor: pointer; }
.rp-play:active { transform: scale(0.96); }
.rp-note { text-align: center; font-size: 0.78rem; color: var(--ink-soft); padding-top: 1.3rem; }
.rp-note strong { color: var(--ink); }
.rp-badges { display: flex; justify-content: center; gap: 0.5rem; margin-top: 0.9rem; flex-wrap: wrap; }
.rp-badge { font-family: 'IBM Plex Mono', monospace; font-size: 0.62rem; padding: 0.22rem 0.55rem; border: 1.5px solid var(--line); color: var(--ink-soft); }
.rp-badge.bad { border-color: var(--bad); color: var(--bad); background: var(--bad-soft); }
.rp-badge.good { border-color: var(--good); color: var(--good); background: var(--good-soft); }
@media (prefers-reduced-motion: reduce) {
.infographic-replaceel *, .infographic-replaceel *::before, .infographic-replaceel *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="rp-wrap">
<div class="rp-hero">
<h1>Replacing an element</h1>
<p>Same result, two ways to ask for it.</p>
</div>
<div class="rp-tabs">
<button class="rp-tab is-active" data-tab="old" type="button">replaceChild()</button>
<button class="rp-tab" data-tab="new" type="button">replaceWith()</button>
</div>
<!-- replaceChild -->
<div class="rp-panel is-active" data-panel="old">
<div class="rp-code"><span class="tok-kw">const</span> <span class="tok-var">menu</span> <span class="tok-punc">=</span> <span class="tok-var">document</span><span class="tok-punc">.</span><span class="tok-fn">getElementById</span><span class="tok-punc">(</span><span class="tok-str">'menu'</span><span class="tok-punc">);</span>
<span class="tok-kw">const</span> <span class="tok-var">li</span> <span class="tok-punc">=</span> <span class="tok-var">document</span><span class="tok-punc">.</span><span class="tok-fn">createElement</span><span class="tok-punc">(</span><span class="tok-str">'li'</span><span class="tok-punc">);</span>
<span class="tok-var">li</span><span class="tok-punc">.</span><span class="tok-var">textContent</span> <span class="tok-punc">=</span> <span class="tok-str">'Home'</span><span class="tok-punc">;</span>
<span class="tok-var">menu</span><span class="tok-punc">.</span><span class="tok-fn">replaceChild</span><span class="tok-punc">(</span><span class="tok-var">li</span><span class="tok-punc">,</span> <span class="tok-var">menu</span><span class="tok-punc">.</span><span class="tok-var">firstElementChild</span><span class="tok-punc">);</span></div>
<div class="rp-page">
<div class="rp-page-bar"><div class="rp-page-dot"></div><div class="rp-page-dot"></div><div class="rp-page-dot"></div></div>
<div class="rp-page-body">
<span style="font-family:'IBM Plex Mono',monospace;font-size:0.6rem;color:var(--ink-soft);display:block;margin-bottom:0.4rem;"><ul id="menu"></span>
<div class="rp-slot">
<div class="rp-item old" id="oldItem">Homepage</div>
<div class="rp-item new" id="newItem">Home</div>
</div>
<div class="rp-static">Services</div>
<div class="rp-static">About</div>
<div class="rp-static">Contact</div>
</div>
</div>
<button class="rp-play" data-run="old" type="button">run</button>
<div class="rp-badges">
<span class="rp-badge bad">needs the parent: menu.replaceChild(new, old)</span>
</div>
<p class="rp-note">You have to reach up to the <strong>parent</strong> to swap one of its children.</p>
</div>
<!-- replaceWith -->
<div class="rp-panel" data-panel="new">
<div class="rp-code"><span class="tok-kw">const</span> <span class="tok-var">firstItem</span> <span class="tok-punc">=</span> <span class="tok-var">document</span><span class="tok-punc">.</span><span class="tok-fn">querySelector</span><span class="tok-punc">(</span><span class="tok-str">'#menu li'</span><span class="tok-punc">);</span>
<span class="tok-kw">const</span> <span class="tok-var">newLi</span> <span class="tok-punc">=</span> <span class="tok-var">document</span><span class="tok-punc">.</span><span class="tok-fn">createElement</span><span class="tok-punc">(</span><span class="tok-str">'li'</span><span class="tok-punc">);</span>
<span class="tok-var">newLi</span><span class="tok-punc">.</span><span class="tok-var">textContent</span> <span class="tok-punc">=</span> <span class="tok-str">'Home'</span><span class="tok-punc">;</span>
<span class="tok-var">firstItem</span><span class="tok-punc">.</span><span class="tok-fn">replaceWith</span><span class="tok-punc">(</span><span class="tok-var">newLi</span><span class="tok-punc">);</span></div>
<div class="rp-page">
<div class="rp-page-bar"><div class="rp-page-dot"></div><div class="rp-page-dot"></div><div class="rp-page-dot"></div></div>
<div class="rp-page-body">
<span style="font-family:'IBM Plex Mono',monospace;font-size:0.6rem;color:var(--ink-soft);display:block;margin-bottom:0.4rem;"><ul id="menu"></span>
<div class="rp-slot">
<div class="rp-item old" id="oldItem2">Homepage</div>
<div class="rp-item new" id="newItem2">Home</div>
</div>
<div class="rp-static">Services</div>
<div class="rp-static">About</div>
<div class="rp-static">Contact</div>
</div>
</div>
<button class="rp-play" data-run="new" type="button">run</button>
<div class="rp-badges">
<span class="rp-badge good">firstItem.replaceWith(newLi) — no parent lookup</span>
</div>
<p class="rp-note">Called <strong>directly on the element</strong> being swapped out — it finds its own spot.</p>
</div>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-replaceel')
|| document.querySelector('.infographic-replaceel');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
wrapper.querySelectorAll('.rp-tab').forEach(tab => {
tab.addEventListener('click', () => {
wrapper.querySelectorAll('.rp-tab').forEach(t => t.classList.remove('is-active'));
wrapper.querySelectorAll('.rp-panel').forEach(p => p.classList.remove('is-active'));
tab.classList.add('is-active');
wrapper.querySelector('.rp-panel[data-panel="' + tab.dataset.tab + '"]').classList.add('is-active');
});
});
function runSwap(oldId, newId) {
const oldEl = wrapper.querySelector('#' + oldId);
const newEl = wrapper.querySelector('#' + newId);
oldEl.classList.remove('is-out');
newEl.classList.remove('is-in');
void oldEl.offsetWidth;
setTimeout(() => oldEl.classList.add('is-out'), 80);
setTimeout(() => newEl.classList.add('is-in'), 450);
}
wrapper.querySelector('[data-run="old"]').addEventListener('click', () => runSwap('oldItem', 'newItem'));
wrapper.querySelector('[data-run="new"]').addEventListener('click', () => runSwap('oldItem2', 'newItem2'));
})();
</script>✅ cloneNode() – clone an element and all of its descendants
🔹 What is cloneNode()?
cloneNode()is a DOM method used to create a copy of an existing node.It belongs to the Node interface.
✏️ Syntax
const clonedNode = originalNode.cloneNode(deep);💊 Parameters
deep (optional)
true→ Clones the node and all its child elementsfalse→ Clones only the node itself (no children)Default:
false
👀 Return Value
Returns a new copy of the original node
❗️ Important Usage Notes
Copies:
HTML structure
Attributes
Inline event handlers (e.g.,
onclick="")
❌ Does NOT copy:
Event listeners added using
addEventListener()
⚠️ If the cloned node has an
id, it will be duplicated→ Always change the id before inserting into DOM
1️⃣ Clone an element with all children (Deep Clone)
✏️ HTML
<ul id="menu">
<li>Home</li>
<li>Services</li>
<li>About</li>
<li>Contact</li>
</ul>🧠 JavaScript
const menu = document.querySelector('#menu');
// deep clone (includes children)
const clonedMenu = menu.cloneNode(true);
// change id to avoid duplication
clonedMenu.id = 'menu-mobile';
// insert into DOM
document.body.appendChild(clonedMenu);<ul id="menu">
<li>Home</li>
<li>Services</li>
<li>About</li>
<li>Contact</li>
</ul>
<ul id="menu-mobile">
<li>Home</li>
<li>Services</li>
<li>About</li>
<li>Contact</li>
</ul>📌 A full copy of the menu is added to the page.
2️⃣ Shallow clone (without children)
🧠 Code
const shallowClone = menu.cloneNode(false);
document.body.appendChild(shallowClone);<ul id="menu"></ul>📌 Only the <ul> is cloned — no <li> elements.
🔁 When to Use cloneNode()
Creating mobile menus
Duplicating cards or templates
Reusing UI components
<div class="infographic-clonenode">
<style>
.infographic-clonenode {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--good: #1a8a5f;
--good-soft: #e1f2ea;
--amber: #a4720a;
--amber-soft: #faf1de;
box-sizing: border-box;
max-width: 880px;
margin: 0 auto;
font-family: 'Inter', system-ui, sans-serif;
color: var(--ink);
background: var(--paper);
overflow-x: hidden;
}
.infographic-clonenode[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--good: #4fbf8f;
--good-soft: #16281f;
--amber: #d9a94a;
--amber-soft: #2c2413;
}
.infographic-clonenode * { box-sizing: border-box; }
.infographic-clonenode h1 { font-family: 'Fraunces', Georgia, serif; font-weight: 600; margin: 0; }
.infographic-clonenode p { margin: 0; }
.infographic-clonenode button { font-family: inherit; }
.cl-wrap { padding: clamp(1.25rem, 5vw, 2.5rem) clamp(1.1rem, 5vw, 3rem) 2rem; }
.cl-hero { text-align: center; margin-bottom: 1.2rem; }
.cl-hero h1 { font-size: clamp(1.35rem, 4.5vw, 1.85rem); }
.cl-hero p { color: var(--ink-soft); margin-top: 0.4rem; font-size: 0.84rem; }
.cl-tabs { display: flex; flex-wrap: wrap; gap: 0.4rem; justify-content: center; margin-bottom: 1.2rem; }
.cl-tab { border: 1px solid var(--line); background: var(--paper-alt); color: var(--ink-soft); padding: 0.36rem 0.65rem; font-size: 0.66rem; font-weight: 700; cursor: pointer; font-family: 'IBM Plex Mono', monospace; }
.cl-tab.is-active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
.cl-tab:hover:not(.is-active) { border-color: var(--ink-soft); color: var(--ink); }
.cl-panel { display: none; }
.cl-panel.is-active { display: block; }
.cl-code { background: #1e1e1e; color: #d4d4d4; border-radius: 5px; padding: 0.6rem 0.8rem; font-family: 'IBM Plex Mono', monospace; font-size: 0.66rem; line-height: 1.6; margin-bottom: 1rem; white-space: pre; overflow-x: auto; }
.tok-kw { color: #569cd6; }
.tok-fn { color: #dcdcaa; }
.tok-str { color: #ce9178; }
.tok-var { color: #9cdcfe; }
.tok-punc { color: #d4d4d4; }
.tok-com { color: #6a9955; }
.cl-lists { display: grid; grid-template-columns: 1fr 1fr; gap: 0.7rem; }
@media (max-width: 480px) { .cl-lists { grid-template-columns: 1fr; } }
.cl-listbox { border: 1.5px solid var(--line); background: var(--paper-alt); border-radius: 6px; padding: 0.6rem 0.7rem; min-height: 9em; }
.cl-listbox .cl-listtitle { font-family: 'IBM Plex Mono', monospace; font-size: 0.62rem; color: var(--ink-soft); margin-bottom: 0.45rem; text-align: center; }
.cl-litem { border: 1.5px solid var(--line); border-radius: 4px; padding: 0.3rem 0.5rem; font-size: 0.76rem; margin-bottom: 0.3rem; background: var(--paper); }
.cl-clone-box { border: 1.5px dashed var(--line); border-radius: 5px; padding: 0.4rem; min-height: 6.5em; opacity: 0.3; transition: opacity 0.4s ease, border-color 0.4s ease; }
.cl-clone-box.is-shown { opacity: 1; border-color: var(--good); border-style: solid; background: var(--good-soft); }
.cl-clone-item { border: 1.5px solid var(--line); border-radius: 4px; padding: 0.3rem 0.5rem; font-size: 0.76rem; margin-bottom: 0.3rem; background: var(--paper); opacity: 0; transform: translateY(-6px) scale(0.95); transition: opacity 0.35s ease, transform 0.35s ease; }
.cl-clone-item.is-in { opacity: 1; transform: translateY(0) scale(1); }
.cl-empty-note { text-align: center; font-family: 'IBM Plex Mono', monospace; font-size: 0.62rem; color: var(--ink-soft); opacity: 0; transition: opacity 0.4s ease; padding: 0.6rem 0; }
.cl-empty-note.is-shown { opacity: 1; }
.cl-play { display: block; margin: 1rem auto 0; border: none; background: var(--accent); color: #fff; padding: 0.5rem 1.2rem; font-size: 0.8rem; font-weight: 600; cursor: pointer; }
.cl-play:active { transform: scale(0.96); }
.cl-note { text-align: center; font-size: 0.78rem; color: var(--ink-soft); margin-top: 1.3rem; }
.cl-note strong { color: var(--ink); }
.cl-usecases { display: flex; justify-content: center; gap: 0.5rem; margin-top: 1.4rem; flex-wrap: wrap; }
.cl-usecase { font-family: 'IBM Plex Mono', monospace; font-size: 0.64rem; padding: 0.25rem 0.6rem; border: 1px solid var(--line); color: var(--ink-soft); background: var(--paper-alt); }
@media (prefers-reduced-motion: reduce) {
.infographic-clonenode *, .infographic-clonenode *::before, .infographic-clonenode *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="cl-wrap">
<div class="cl-hero">
<h1>cloneNode()</h1>
<p>One argument decides whether the children come along for the ride.</p>
</div>
<div class="cl-tabs">
<button class="cl-tab is-active" data-tab="deep" type="button">cloneNode(true) — deep</button>
<button class="cl-tab" data-tab="shallow" type="button">cloneNode(false) — shallow</button>
</div>
<!-- deep -->
<div class="cl-panel is-active" data-panel="deep">
<div class="cl-code"><span class="tok-kw">const</span> <span class="tok-var">menu</span> <span class="tok-punc">=</span> <span class="tok-var">document</span><span class="tok-punc">.</span><span class="tok-fn">querySelector</span><span class="tok-punc">(</span><span class="tok-str">'#menu'</span><span class="tok-punc">);</span>
<span class="tok-kw">const</span> <span class="tok-var">clonedMenu</span> <span class="tok-punc">=</span> <span class="tok-var">menu</span><span class="tok-punc">.</span><span class="tok-fn">cloneNode</span><span class="tok-punc">(</span><span class="tok-kw">true</span><span class="tok-punc">);</span>
<span class="tok-var">clonedMenu</span><span class="tok-punc">.</span><span class="tok-var">id</span> <span class="tok-punc">=</span> <span class="tok-str">'menu-mobile'</span><span class="tok-punc">;</span>
<span class="tok-var">document</span><span class="tok-punc">.</span><span class="tok-var">body</span><span class="tok-punc">.</span><span class="tok-fn">appendChild</span><span class="tok-punc">(</span><span class="tok-var">clonedMenu</span><span class="tok-punc">);</span></div>
<div class="cl-lists">
<div class="cl-listbox">
<div class="cl-listtitle">#menu (original)</div>
<div class="cl-litem">Home</div>
<div class="cl-litem">Services</div>
<div class="cl-litem">About</div>
<div class="cl-litem">Contact</div>
</div>
<div class="cl-listbox">
<div class="cl-listtitle">#menu-mobile (clone)</div>
<div class="cl-clone-box" id="deepBox">
<div class="cl-clone-item" id="d1">Home</div>
<div class="cl-clone-item" id="d2">Services</div>
<div class="cl-clone-item" id="d3">About</div>
<div class="cl-clone-item" id="d4">Contact</div>
</div>
</div>
</div>
<button class="cl-play" data-run="deep" type="button">run</button>
<p class="cl-note">Every <strong><li></strong> comes with it — a full, independent copy of the whole subtree.</p>
</div>
<!-- shallow -->
<div class="cl-panel" data-panel="shallow">
<div class="cl-code"><span class="tok-kw">const</span> <span class="tok-var">shallowClone</span> <span class="tok-punc">=</span> <span class="tok-var">menu</span><span class="tok-punc">.</span><span class="tok-fn">cloneNode</span><span class="tok-punc">(</span><span class="tok-kw">false</span><span class="tok-punc">);</span>
<span class="tok-var">document</span><span class="tok-punc">.</span><span class="tok-var">body</span><span class="tok-punc">.</span><span class="tok-fn">appendChild</span><span class="tok-punc">(</span><span class="tok-var">shallowClone</span><span class="tok-punc">);</span></div>
<div class="cl-lists">
<div class="cl-listbox">
<div class="cl-listtitle">#menu (original)</div>
<div class="cl-litem">Home</div>
<div class="cl-litem">Services</div>
<div class="cl-litem">About</div>
<div class="cl-litem">Contact</div>
</div>
<div class="cl-listbox">
<div class="cl-listtitle">clone</div>
<div class="cl-clone-box" id="shallowBox">
<div class="cl-empty-note" id="shallowEmpty"><ul></ul> — no children</div>
</div>
</div>
</div>
<button class="cl-play" data-run="shallow" type="button">run</button>
<p class="cl-note">Only the <strong><ul></strong> itself — the tag copies, the four <li>s don't.</p>
</div>
<div class="cl-usecases">
<span class="cl-usecase">mobile menus</span>
<span class="cl-usecase">duplicating cards</span>
<span class="cl-usecase">reusable templates</span>
</div>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-clonenode')
|| document.querySelector('.infographic-clonenode');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
wrapper.querySelectorAll('.cl-tab').forEach(tab => {
tab.addEventListener('click', () => {
wrapper.querySelectorAll('.cl-tab').forEach(t => t.classList.remove('is-active'));
wrapper.querySelectorAll('.cl-panel').forEach(p => p.classList.remove('is-active'));
tab.classList.add('is-active');
wrapper.querySelector('.cl-panel[data-panel="' + tab.dataset.tab + '"]').classList.add('is-active');
});
});
wrapper.querySelector('[data-run="deep"]').addEventListener('click', () => {
const box = wrapper.querySelector('#deepBox');
const items = ['d1', 'd2', 'd3', 'd4'].map(id => wrapper.querySelector('#' + id));
box.classList.remove('is-shown');
items.forEach(i => i.classList.remove('is-in'));
void box.offsetWidth;
setTimeout(() => box.classList.add('is-shown'), 60);
items.forEach((item, i) => setTimeout(() => item.classList.add('is-in'), 250 + i * 180));
});
wrapper.querySelector('[data-run="shallow"]').addEventListener('click', () => {
const box = wrapper.querySelector('#shallowBox');
const empty = wrapper.querySelector('#shallowEmpty');
box.classList.remove('is-shown');
empty.classList.remove('is-shown');
void box.offsetWidth;
setTimeout(() => box.classList.add('is-shown'), 60);
setTimeout(() => empty.classList.add('is-shown'), 350);
});
})();
</script>✅ removeChild() – remove child elements of a node
🔹 What is removeChild()?
removeChild()is a DOM method used to remove a child node from its parent.It works only when the node is a direct child of the parent.
✏️ Syntax
parentNode.removeChild(childNode);💊 Parameters
childNode→ The child node to be removed
❌ If childNode is not a child of parentNode, an error is thrown.
👀 Return Value
Returns the removed node
The node is removed from DOM, but still exists in memory
1️⃣ Remove a single child element
✏️ HTML
<ul id="menu">
<li>Home</li>
<li>Products</li>
<li>About Us</li>
</ul>🧠 JavaScript
const menu = document.getElementById('menu');
// remove last item
menu.removeChild(menu.lastElementChild);<ul id="menu">
<li>Home</li>
<li>Products</li>
</ul>📌 The last <li> is removed.
2️⃣ Store the removed node (optional)
const removedItem = menu.removeChild(menu.firstElementChild);
// still accessible in memory
console.log(removedItem.textContent); // Home📌 Useful if you want to reinsert later.
3️⃣ Remove all child nodes (loop method)
const menu = document.getElementById('menu');
while (menu.firstChild) {
menu.removeChild(menu.firstChild);
}📌 Removes nodes one by one safely.
4️⃣ Remove all children (quick way)
menu.innerHTML = '';📌 Fast but:
❌ Removes everything instantly
❌ Also removes attached event handlers
🔁 Modern Alternative
element.remove();Example:
menu.lastElementChild.remove();✔️ Cleaner
✔️ No parent reference needed
<div class="infographic-removechild">
<style>
.infographic-removechild {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--good: #1a8a5f;
--good-soft: #e1f2ea;
--bad: #c8452e;
--bad-soft: #f7e3df;
box-sizing: border-box;
max-width: 880px;
margin: 0 auto;
font-family: 'Inter', system-ui, sans-serif;
color: var(--ink);
background: var(--paper);
overflow-x: hidden;
}
.infographic-removechild[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--good: #4fbf8f;
--good-soft: #16281f;
--bad: #e0715a;
--bad-soft: #2e211d;
}
.infographic-removechild * { box-sizing: border-box; }
.infographic-removechild h1 { font-family: 'Fraunces', Georgia, serif; font-weight: 600; margin: 0; }
.infographic-removechild p { margin: 0; }
.infographic-removechild button { font-family: inherit; }
.rc-wrap { padding: clamp(1.25rem, 5vw, 2.5rem) clamp(1.1rem, 5vw, 3rem) 2rem; }
.rc-hero { text-align: center; margin-bottom: 1.2rem; }
.rc-hero h1 { font-size: clamp(1.35rem, 4.5vw, 1.85rem); }
.rc-hero p { color: var(--ink-soft); margin-top: 0.4rem; font-size: 0.84rem; }
.rc-tabs { display: flex; flex-wrap: wrap; gap: 0.35rem; justify-content: center; margin-bottom: 1.2rem; }
.rc-tab { border: 1px solid var(--line); background: var(--paper-alt); color: var(--ink-soft); padding: 0.34rem 0.55rem; font-size: 0.6rem; font-weight: 700; cursor: pointer; font-family: 'IBM Plex Mono', monospace; }
.rc-tab.is-active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
.rc-tab:hover:not(.is-active) { border-color: var(--ink-soft); color: var(--ink); }
.rc-panel { display: none; }
.rc-panel.is-active { display: block; }
.rc-code { background: #1e1e1e; color: #d4d4d4; border-radius: 5px; padding: 0.6rem 0.8rem; font-family: 'IBM Plex Mono', monospace; font-size: 0.66rem; line-height: 1.6; margin-bottom: 1rem; white-space: pre; overflow-x: auto; }
.tok-kw { color: #569cd6; }
.tok-fn { color: #dcdcaa; }
.tok-str { color: #ce9178; }
.tok-var { color: #9cdcfe; }
.tok-punc { color: #d4d4d4; }
.tok-com { color: #6a9955; }
.rc-page { border: 1.5px solid var(--line); background: var(--paper-alt); border-radius: 6px; overflow: hidden; margin-bottom: 1rem; }
.rc-page-bar { background: #2b2b2b; padding: 0.4rem 0.6rem; display: flex; gap: 0.3rem; }
.rc-page-dot { width: 8px; height: 8px; border-radius: 50%; background: #555; }
.rc-page-body { padding: 0.9rem 1rem; background: var(--paper); }
.rc-item { border: 1.5px solid var(--line); border-radius: 4px; padding: 0.32rem 0.55rem; font-size: 0.8rem; margin-bottom: 0.3rem; transition: opacity 0.35s ease, transform 0.35s ease, max-height 0.35s ease, padding 0.35s ease, margin 0.35s ease, border-color 0.35s ease, background 0.35s ease; }
.rc-item.is-out { opacity: 0; transform: scale(0.9); max-height: 0; padding-top: 0; padding-bottom: 0; margin-bottom: 0; border-width: 0; }
.rc-item .rc-listen-badge { font-size: 0.56rem; color: var(--accent); margin-left: 0.4rem; }
.rc-memory { width: min(220px, 100%); margin: 0.8rem auto 0; text-align: center; border: 1.5px dashed var(--line); border-radius: 6px; padding: 0.5rem 0.6rem; opacity: 0; transition: opacity 0.4s ease, border-color 0.4s ease; }
.rc-memory.is-shown { opacity: 1; border-color: var(--good); }
.rc-memory-label { font-family: 'IBM Plex Mono', monospace; font-size: 0.56rem; color: var(--ink-soft); display: block; margin-bottom: 0.2rem; }
.rc-memory-content { font-family: 'IBM Plex Mono', monospace; font-size: 0.7rem; color: var(--good); font-weight: 700; }
.rc-play { display: block; margin: 1rem auto 0; border: none; background: var(--accent); color: #fff; padding: 0.5rem 1.2rem; font-size: 0.8rem; font-weight: 600; cursor: pointer; }
.rc-play:active { transform: scale(0.96); }
.rc-play:disabled { opacity: 0.45; cursor: default; }
.rc-console { margin: 1rem auto 0; max-width: 320px; text-align: left; border: 1.5px solid var(--line); background: var(--paper-alt); padding: 0.5rem 0.75rem; font-family: 'IBM Plex Mono', monospace; font-size: 0.68rem; min-height: 1.8em; }
.rc-console .rc-cline { opacity: 0; transition: opacity 0.25s ease; color: var(--good); display: block; }
.rc-console .rc-cline.is-shown { opacity: 1; }
.rc-note { text-align: center; font-size: 0.78rem; color: var(--ink-soft); padding-top: 1.3rem; }
.rc-note strong { color: var(--ink); }
.rc-badge { display: block; width: fit-content; margin: 0.9rem auto 0; font-family: 'IBM Plex Mono', monospace; font-size: 0.62rem; padding: 0.22rem 0.55rem; border: 1.5px solid var(--line); color: var(--ink-soft); }
.rc-badge.good { border-color: var(--good); color: var(--good); background: var(--good-soft); }
.rc-badge.bad { border-color: var(--bad); color: var(--bad); background: var(--bad-soft); }
@media (prefers-reduced-motion: reduce) {
.infographic-removechild *, .infographic-removechild *::before, .infographic-removechild *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="rc-wrap">
<div class="rc-hero">
<h1>Removing elements</h1>
<p>One item, all of them, or something in between — and what happens to what's removed.</p>
</div>
<div class="rc-tabs">
<button class="rc-tab is-active" data-tab="single" type="button">removeChild()</button>
<button class="rc-tab" data-tab="store" type="button">store the removed node</button>
<button class="rc-tab" data-tab="loop" type="button">remove all — loop</button>
<button class="rc-tab" data-tab="innerhtml" type="button">remove all — innerHTML</button>
<button class="rc-tab" data-tab="modern" type="button">.remove()</button>
</div>
<!-- single -->
<div class="rc-panel is-active" data-panel="single">
<div class="rc-code"><span class="tok-kw">const</span> <span class="tok-var">menu</span> <span class="tok-punc">=</span> <span class="tok-var">document</span><span class="tok-punc">.</span><span class="tok-fn">getElementById</span><span class="tok-punc">(</span><span class="tok-str">'menu'</span><span class="tok-punc">);</span>
<span class="tok-var">menu</span><span class="tok-punc">.</span><span class="tok-fn">removeChild</span><span class="tok-punc">(</span><span class="tok-var">menu</span><span class="tok-punc">.</span><span class="tok-var">lastElementChild</span><span class="tok-punc">);</span></div>
<div class="rc-page">
<div class="rc-page-bar"><div class="rc-page-dot"></div><div class="rc-page-dot"></div><div class="rc-page-dot"></div></div>
<div class="rc-page-body">
<span style="font-family:'IBM Plex Mono',monospace;font-size:0.6rem;color:var(--ink-soft);display:block;margin-bottom:0.4rem;"><ul id="menu"></span>
<div class="rc-item" id="s1">Home</div>
<div class="rc-item" id="s2">Products</div>
<div class="rc-item" id="s3">About Us</div>
</div>
</div>
<button class="rc-play" data-run="single" type="button">run</button>
<p class="rc-note">Needs the <strong>parent</strong> to remove one of its own children.</p>
</div>
<!-- store -->
<div class="rc-panel" data-panel="store">
<div class="rc-code"><span class="tok-kw">const</span> <span class="tok-var">removedItem</span> <span class="tok-punc">=</span> <span class="tok-var">menu</span><span class="tok-punc">.</span><span class="tok-fn">removeChild</span><span class="tok-punc">(</span><span class="tok-var">menu</span><span class="tok-punc">.</span><span class="tok-var">firstElementChild</span><span class="tok-punc">);</span>
<span class="tok-var">console</span><span class="tok-punc">.</span><span class="tok-fn">log</span><span class="tok-punc">(</span><span class="tok-var">removedItem</span><span class="tok-punc">.</span><span class="tok-var">textContent</span><span class="tok-punc">);</span></div>
<div class="rc-page">
<div class="rc-page-bar"><div class="rc-page-dot"></div><div class="rc-page-dot"></div><div class="rc-page-dot"></div></div>
<div class="rc-page-body">
<span style="font-family:'IBM Plex Mono',monospace;font-size:0.6rem;color:var(--ink-soft);display:block;margin-bottom:0.4rem;"><ul id="menu"></span>
<div class="rc-item" id="st1">Home</div>
<div class="rc-item" id="st2">Products</div>
<div class="rc-item" id="st3">About Us</div>
</div>
</div>
<div class="rc-memory" id="storeMemory">
<span class="rc-memory-label">removedItem — still in memory</span>
<div class="rc-memory-content">"Home"</div>
</div>
<button class="rc-play" data-run="store" type="button">run</button>
<div class="rc-console"><span class="rc-cline" id="outStore">Home</span></div>
<p class="rc-note"><strong>removeChild()</strong> returns the node it removed — gone from the page, not gone from existence.</p>
</div>
<!-- loop -->
<div class="rc-panel" data-panel="loop">
<div class="rc-code"><span class="tok-kw">while</span> <span class="tok-punc">(</span><span class="tok-var">menu</span><span class="tok-punc">.</span><span class="tok-var">firstChild</span><span class="tok-punc">) {</span>
<span class="tok-var">menu</span><span class="tok-punc">.</span><span class="tok-fn">removeChild</span><span class="tok-punc">(</span><span class="tok-var">menu</span><span class="tok-punc">.</span><span class="tok-var">firstChild</span><span class="tok-punc">);</span>
<span class="tok-punc">}</span></div>
<div class="rc-page">
<div class="rc-page-bar"><div class="rc-page-dot"></div><div class="rc-page-dot"></div><div class="rc-page-dot"></div></div>
<div class="rc-page-body">
<span style="font-family:'IBM Plex Mono',monospace;font-size:0.6rem;color:var(--ink-soft);display:block;margin-bottom:0.4rem;"><ul id="menu"></span>
<div class="rc-item" id="l1">Home</div>
<div class="rc-item" id="l2">Products</div>
<div class="rc-item" id="l3">About Us</div>
</div>
</div>
<button class="rc-play" data-run="loop" type="button">run</button>
<p class="rc-note">One at a time, safely — each loop always removes whatever is <strong>now</strong> first.</p>
</div>
<!-- innerHTML -->
<div class="rc-panel" data-panel="innerhtml">
<div class="rc-code"><span class="tok-var">menu</span><span class="tok-punc">.</span><span class="tok-var">innerHTML</span> <span class="tok-punc">=</span> <span class="tok-str">''</span><span class="tok-punc">;</span></div>
<div class="rc-page">
<div class="rc-page-bar"><div class="rc-page-dot"></div><div class="rc-page-dot"></div><div class="rc-page-dot"></div></div>
<div class="rc-page-body">
<span style="font-family:'IBM Plex Mono',monospace;font-size:0.6rem;color:var(--ink-soft);display:block;margin-bottom:0.4rem;"><ul id="menu"></span>
<div class="rc-item" id="i1">Home <span class="rc-listen-badge">🔔 click listener</span></div>
<div class="rc-item" id="i2">Products</div>
<div class="rc-item" id="i3">About Us</div>
</div>
</div>
<button class="rc-play" data-run="innerhtml" type="button">run</button>
<span class="rc-badge bad">instant, but the click listener on "Home" is gone too</span>
<p class="rc-note">Fastest way to clear everything — at the cost of anything attached to those elements.</p>
</div>
<!-- modern -->
<div class="rc-panel" data-panel="modern">
<div class="rc-code"><span class="tok-var">menu</span><span class="tok-punc">.</span><span class="tok-var">lastElementChild</span><span class="tok-punc">.</span><span class="tok-fn">remove</span><span class="tok-punc">();</span></div>
<div class="rc-page">
<div class="rc-page-bar"><div class="rc-page-dot"></div><div class="rc-page-dot"></div><div class="rc-page-dot"></div></div>
<div class="rc-page-body">
<span style="font-family:'IBM Plex Mono',monospace;font-size:0.6rem;color:var(--ink-soft);display:block;margin-bottom:0.4rem;"><ul id="menu"></span>
<div class="rc-item" id="m1">Home</div>
<div class="rc-item" id="m2">Products</div>
<div class="rc-item" id="m3">About Us</div>
</div>
</div>
<button class="rc-play" data-run="modern" type="button">run</button>
<span class="rc-badge good">called directly on the element — no parent reference needed</span>
<p class="rc-note">Same result as <strong>removeChild()</strong>, just asked for the modern way.</p>
</div>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-removechild')
|| document.querySelector('.infographic-removechild');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
wrapper.querySelectorAll('.rc-tab').forEach(tab => {
tab.addEventListener('click', () => {
wrapper.querySelectorAll('.rc-tab').forEach(t => t.classList.remove('is-active'));
wrapper.querySelectorAll('.rc-panel').forEach(p => p.classList.remove('is-active'));
tab.classList.add('is-active');
wrapper.querySelector('.rc-panel[data-panel="' + tab.dataset.tab + '"]').classList.add('is-active');
});
});
/* single removeChild */
wrapper.querySelector('[data-run="single"]').addEventListener('click', () => {
const el = wrapper.querySelector('#s3');
el.classList.remove('is-out');
void el.offsetWidth;
setTimeout(() => el.classList.add('is-out'), 80);
});
/* store removed node */
wrapper.querySelector('[data-run="store"]').addEventListener('click', () => {
const el = wrapper.querySelector('#st1');
const mem = wrapper.querySelector('#storeMemory');
const out = wrapper.querySelector('#outStore');
el.classList.remove('is-out');
mem.classList.remove('is-shown');
out.classList.remove('is-shown');
void el.offsetWidth;
setTimeout(() => el.classList.add('is-out'), 80);
setTimeout(() => mem.classList.add('is-shown'), 350);
setTimeout(() => out.classList.add('is-shown'), 550);
});
/* loop */
wrapper.querySelector('[data-run="loop"]').addEventListener('click', () => {
const items = ['l1', 'l2', 'l3'].map(id => wrapper.querySelector('#' + id));
items.forEach(i => i.classList.remove('is-out'));
void items[0].offsetWidth;
items.forEach((item, i) => setTimeout(() => item.classList.add('is-out'), 200 + i * 380));
});
/* innerHTML clear */
wrapper.querySelector('[data-run="innerhtml"]').addEventListener('click', () => {
const items = ['i1', 'i2', 'i3'].map(id => wrapper.querySelector('#' + id));
items.forEach(i => i.classList.remove('is-out'));
void items[0].offsetWidth;
setTimeout(() => { items.forEach(i => i.classList.add('is-out')); }, 120);
});
/* modern remove() */
wrapper.querySelector('[data-run="modern"]').addEventListener('click', () => {
const el = wrapper.querySelector('#m3');
el.classList.remove('is-out');
void el.offsetWidth;
setTimeout(() => el.classList.add('is-out'), 80);
});
})();
</script>✅ insertBefore() - insert a new node before an existing node as a child node of a specified parent node
🔹 What is insertBefore()?
insertBefore()is a DOM method used to insert a new node before an existing child node.It works on the parent node.
✏️ Syntax
parentNode.insertBefore(newNode, existingNode);💊 Parameters
newNode→ Node to be insertedexistingNode→ Node before which the new node is insertedIf
existingNodeisnull, the node is added at the end
👀 Return Value
Returns the inserted node
1️⃣ Insert an element before another element
✏️ HTML
<ul id="menu">
<li>Services</li>
<li>About</li>
<li>Contact</li>
</ul>🧠 JavaScript
const menu = document.getElementById('menu');
// create new <li>
const li = document.createElement('li');
li.textContent = 'Home';
// insert before first item
menu.insertBefore(li, menu.firstElementChild);<ul id="menu">
<li>Home</li>
<li>Services</li>
<li>About</li>
<li>Contact</li>
</ul>📌 The new <li> is added at the beginning.
2️⃣ Insert at the end using null
menu.insertBefore(li, null);📌 Same effect as appendChild().
3️⃣ Helper function (optional)
function insertBefore(newNode, existingNode) {
existingNode.parentNode.insertBefore(newNode, existingNode);
}📌 Useful when the parent is not directly available.
🔁 Modern Alternatives
Example:
menu.firstElementChild.before(li);<div class="infographic-insertbefore">
<style>
.infographic-insertbefore {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--good: #1a8a5f;
--good-soft: #e1f2ea;
box-sizing: border-box;
max-width: 880px;
margin: 0 auto;
font-family: 'Inter', system-ui, sans-serif;
color: var(--ink);
background: var(--paper);
overflow-x: hidden;
}
.infographic-insertbefore[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--good: #4fbf8f;
--good-soft: #16281f;
}
.infographic-insertbefore * { box-sizing: border-box; }
.infographic-insertbefore h1 { font-family: 'Fraunces', Georgia, serif; font-weight: 600; margin: 0; }
.infographic-insertbefore p { margin: 0; }
.infographic-insertbefore button { font-family: inherit; }
.ib-wrap { padding: clamp(1.25rem, 5vw, 2.5rem) clamp(1.1rem, 5vw, 3rem) 2rem; }
.ib-hero { text-align: center; margin-bottom: 1.2rem; }
.ib-hero h1 { font-size: clamp(1.35rem, 4.5vw, 1.85rem); }
.ib-hero p { color: var(--ink-soft); margin-top: 0.4rem; font-size: 0.84rem; }
.ib-tabs { display: flex; flex-wrap: wrap; gap: 0.35rem; justify-content: center; margin-bottom: 1.2rem; }
.ib-tab { border: 1px solid var(--line); background: var(--paper-alt); color: var(--ink-soft); padding: 0.34rem 0.6rem; font-size: 0.62rem; font-weight: 700; cursor: pointer; font-family: 'IBM Plex Mono', monospace; }
.ib-tab.is-active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
.ib-tab:hover:not(.is-active) { border-color: var(--ink-soft); color: var(--ink); }
.ib-panel { display: none; }
.ib-panel.is-active { display: block; }
.ib-code { background: #1e1e1e; color: #d4d4d4; border-radius: 5px; padding: 0.6rem 0.8rem; font-family: 'IBM Plex Mono', monospace; font-size: 0.66rem; line-height: 1.6; margin-bottom: 1rem; white-space: pre; overflow-x: auto; }
.tok-kw { color: #569cd6; }
.tok-fn { color: #dcdcaa; }
.tok-str { color: #ce9178; }
.tok-var { color: #9cdcfe; }
.tok-punc { color: #d4d4d4; }
.ib-page { border: 1.5px solid var(--line); background: var(--paper-alt); border-radius: 6px; overflow: hidden; margin-bottom: 1rem; }
.ib-page-bar { background: #2b2b2b; padding: 0.4rem 0.6rem; display: flex; gap: 0.3rem; }
.ib-page-dot { width: 8px; height: 8px; border-radius: 50%; background: #555; }
.ib-page-body { padding: 0.9rem 1rem; background: var(--paper); display: flex; flex-direction: column; }
.ib-item { border: 1.5px solid var(--line); border-radius: 4px; padding: 0.32rem 0.55rem; font-size: 0.8rem; margin-bottom: 0.3rem; order: 10; transition: border-color 0.35s ease, background 0.35s ease; }
.ib-item.is-anchor { border-color: var(--accent); background: var(--accent-soft); }
.ib-item.is-new { opacity: 0; transform: scale(0.95); transition: opacity 0.4s ease, transform 0.4s ease, border-color 0.4s ease, background 0.4s ease; }
.ib-item.is-new.is-shown { opacity: 1; transform: scale(1); border-color: var(--good); background: var(--good-soft); }
.ib-play { display: block; margin: 0 auto; border: none; background: var(--accent); color: #fff; padding: 0.5rem 1.2rem; font-size: 0.8rem; font-weight: 600; cursor: pointer; }
.ib-play:active { transform: scale(0.96); }
.ib-note { text-align: center; font-size: 0.78rem; color: var(--ink-soft); padding-top: 1.3rem; }
.ib-note strong { color: var(--ink); }
.ib-badge { display: block; width: fit-content; margin: 0.9rem auto 0; font-family: 'IBM Plex Mono', monospace; font-size: 0.62rem; padding: 0.22rem 0.55rem; border: 1.5px solid var(--good); color: var(--good); background: var(--good-soft); }
/* modern table */
.ib-table { border: 1px solid var(--line); margin-top: 1.1rem; }
.ib-trow { display: grid; grid-template-columns: 1.3fr 1fr; }
.ib-trow + .ib-trow { border-top: 1px solid var(--line); }
.ib-thead { background: var(--paper-alt); font-weight: 700; }
.ib-tcell { padding: 0.4rem 0.6rem; font-size: 0.68rem; }
.ib-tcell.code { font-family: 'IBM Plex Mono', monospace; color: var(--accent); border-left: 1px solid var(--line); }
@media (prefers-reduced-motion: reduce) {
.infographic-insertbefore *, .infographic-insertbefore *::before, .infographic-insertbefore *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="ib-wrap">
<div class="ib-hero">
<h1>insertBefore()</h1>
<p>Position an element relative to an existing one — plus the modern shortcuts for the same jobs.</p>
</div>
<div class="ib-tabs">
<button class="ib-tab is-active" data-tab="basic" type="button">insert at start</button>
<button class="ib-tab" data-tab="null" type="button">null = append</button>
<button class="ib-tab" data-tab="helper" type="button">helper function</button>
<button class="ib-tab" data-tab="modern" type="button">modern alternatives</button>
</div>
<!-- basic -->
<div class="ib-panel is-active" data-panel="basic">
<div class="ib-code"><span class="tok-kw">const</span> <span class="tok-var">menu</span> <span class="tok-punc">=</span> <span class="tok-var">document</span><span class="tok-punc">.</span><span class="tok-fn">getElementById</span><span class="tok-punc">(</span><span class="tok-str">'menu'</span><span class="tok-punc">);</span>
<span class="tok-kw">const</span> <span class="tok-var">li</span> <span class="tok-punc">=</span> <span class="tok-var">document</span><span class="tok-punc">.</span><span class="tok-fn">createElement</span><span class="tok-punc">(</span><span class="tok-str">'li'</span><span class="tok-punc">);</span>
<span class="tok-var">li</span><span class="tok-punc">.</span><span class="tok-var">textContent</span> <span class="tok-punc">=</span> <span class="tok-str">'Home'</span><span class="tok-punc">;</span>
<span class="tok-var">menu</span><span class="tok-punc">.</span><span class="tok-fn">insertBefore</span><span class="tok-punc">(</span><span class="tok-var">li</span><span class="tok-punc">,</span> <span class="tok-var">menu</span><span class="tok-punc">.</span><span class="tok-var">firstElementChild</span><span class="tok-punc">);</span></div>
<div class="ib-page">
<div class="ib-page-bar"><div class="ib-page-dot"></div><div class="ib-page-dot"></div><div class="ib-page-dot"></div></div>
<div class="ib-page-body">
<span style="font-family:'IBM Plex Mono',monospace;font-size:0.6rem;color:var(--ink-soft);display:block;margin-bottom:0.4rem;order:0;"><ul id="menu"></span>
<div class="ib-item is-new" id="b1" style="order:1;">Home</div>
<div class="ib-item is-anchor" style="order:2;">Services</div>
<div class="ib-item" style="order:3;">About</div>
<div class="ib-item" style="order:4;">Contact</div>
</div>
</div>
<button class="ib-play" data-run="basic" type="button">run</button>
<p class="ib-note">Second argument is the <strong>reference node</strong> — the new one lands right before it.</p>
</div>
<!-- null -->
<div class="ib-panel" data-panel="null">
<div class="ib-code"><span class="tok-var">menu</span><span class="tok-punc">.</span><span class="tok-fn">insertBefore</span><span class="tok-punc">(</span><span class="tok-var">li</span><span class="tok-punc">,</span> <span class="tok-kw">null</span><span class="tok-punc">);</span> <span style="color:#6a9955;">// same as appendChild(li)</span></div>
<div class="ib-page">
<div class="ib-page-bar"><div class="ib-page-dot"></div><div class="ib-page-dot"></div><div class="ib-page-dot"></div></div>
<div class="ib-page-body">
<span style="font-family:'IBM Plex Mono',monospace;font-size:0.6rem;color:var(--ink-soft);display:block;margin-bottom:0.4rem;order:0;"><ul id="menu"></span>
<div class="ib-item" style="order:1;">Services</div>
<div class="ib-item" style="order:2;">About</div>
<div class="ib-item is-anchor" style="order:3;">Contact</div>
<div class="ib-item is-new" id="n1" style="order:4;">Home</div>
</div>
</div>
<button class="ib-play" data-run="null" type="button">run</button>
<p class="ib-note">"Insert before <strong>nothing</strong>" just means <strong>at the very end</strong> — no reference node to land in front of.</p>
</div>
<!-- helper -->
<div class="ib-panel" data-panel="helper">
<div class="ib-code"><span class="tok-kw">function</span> <span class="tok-fn">insertBefore</span><span class="tok-punc">(newNode, existingNode) {</span>
<span class="tok-var">existingNode</span><span class="tok-punc">.</span><span class="tok-var">parentNode</span><span class="tok-punc">.</span><span class="tok-fn">insertBefore</span><span class="tok-punc">(newNode, existingNode);</span>
<span class="tok-punc">}</span>
<span class="tok-fn">insertBefore</span><span class="tok-punc">(</span><span class="tok-var">li</span><span class="tok-punc">,</span> <span class="tok-var">servicesItem</span><span class="tok-punc">);</span> <span style="color:#6a9955;">// only have the sibling, not the parent</span></div>
<div class="ib-page">
<div class="ib-page-bar"><div class="ib-page-dot"></div><div class="ib-page-dot"></div><div class="ib-page-dot"></div></div>
<div class="ib-page-body">
<span style="font-family:'IBM Plex Mono',monospace;font-size:0.6rem;color:var(--ink-soft);display:block;margin-bottom:0.4rem;order:0;"><ul id="menu"></span>
<div class="ib-item is-new" id="h1" style="order:1;">Home</div>
<div class="ib-item is-anchor" style="order:2;">Services</div>
<div class="ib-item" style="order:3;">About</div>
<div class="ib-item" style="order:4;">Contact</div>
</div>
</div>
<button class="ib-play" data-run="helper" type="button">run</button>
<p class="ib-note">Reaches up to <strong>parentNode</strong> on your behalf — handy when a function only gets passed a sibling.</p>
</div>
<!-- modern -->
<div class="ib-panel" data-panel="modern">
<div class="ib-code"><span class="tok-var">menu</span><span class="tok-punc">.</span><span class="tok-var">firstElementChild</span><span class="tok-punc">.</span><span class="tok-fn">before</span><span class="tok-punc">(</span><span class="tok-var">li</span><span class="tok-punc">);</span></div>
<div class="ib-page">
<div class="ib-page-bar"><div class="ib-page-dot"></div><div class="ib-page-dot"></div><div class="ib-page-dot"></div></div>
<div class="ib-page-body">
<span style="font-family:'IBM Plex Mono',monospace;font-size:0.6rem;color:var(--ink-soft);display:block;margin-bottom:0.4rem;order:0;"><ul id="menu"></span>
<div class="ib-item is-new" id="mo1" style="order:1;">Home</div>
<div class="ib-item is-anchor" style="order:2;">Services</div>
<div class="ib-item" style="order:3;">About</div>
<div class="ib-item" style="order:4;">Contact</div>
</div>
</div>
<button class="ib-play" data-run="modern" type="button">run</button>
<span class="ib-badge">called directly on the reference element — no parent lookup at all</span>
<div class="ib-table">
<div class="ib-trow ib-thead">
<div class="ib-tcell">task</div>
<div class="ib-tcell code">modern method</div>
</div>
<div class="ib-trow">
<div class="ib-tcell">insert before an element</div>
<div class="ib-tcell code">element.before()</div>
</div>
<div class="ib-trow">
<div class="ib-tcell">insert at the start</div>
<div class="ib-tcell code">parent.prepend()</div>
</div>
</div>
</div>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-insertbefore')
|| document.querySelector('.infographic-insertbefore');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
wrapper.querySelectorAll('.ib-tab').forEach(tab => {
tab.addEventListener('click', () => {
wrapper.querySelectorAll('.ib-tab').forEach(t => t.classList.remove('is-active'));
wrapper.querySelectorAll('.ib-panel').forEach(p => p.classList.remove('is-active'));
tab.classList.add('is-active');
wrapper.querySelector('.ib-panel[data-panel="' + tab.dataset.tab + '"]').classList.add('is-active');
});
});
function runSimple(id) {
const el = wrapper.querySelector('#' + id);
el.classList.remove('is-shown');
void el.offsetWidth;
setTimeout(() => el.classList.add('is-shown'), 120);
}
wrapper.querySelector('[data-run="basic"]').addEventListener('click', () => runSimple('b1'));
wrapper.querySelector('[data-run="null"]').addEventListener('click', () => runSimple('n1'));
wrapper.querySelector('[data-run="helper"]').addEventListener('click', () => runSimple('h1'));
wrapper.querySelector('[data-run="modern"]').addEventListener('click', () => runSimple('mo1'));
})();
</script>