Creating and Removing DOM Nodes — Complete Guide
In this tutorial, you will learn about Creating and Removing DOM Nodes. We cover key concepts, practical examples, and best practices to help you master this topic.
Creating and removing DOM nodes using createElement, appendChild, removeChild, and remove enables dynamic page updates without reloading the entire document from the server.
What You'll Learn
- How to create element nodes, text nodes, and comment nodes
- How to insert new nodes at various positions in the tree
- How to safely remove nodes and clean up resources
- Patterns for efficient bulk creation and insertion
Why It Matters
Modern web applications create and destroy DOM nodes constantly — rendering search results, loading new messages, updating dashboards. Understanding the full lifecycle of node creation and removal prevents memory leaks and ensures smooth performance.
Real-World Use
- A social media feed creates new post elements as the user scrolls and removes them when they scroll away
- A modal library creates overlay elements on demand and removes them on close
- A data grid renders thousands of rows by creating and recycling cell elements
flowchart LR A[Create Node] --> B[createElement] A --> C[createTextNode] B --> D[Configure Properties] D --> E[Insert into DOM] E --> F[appendChild] E --> G[insertBefore] E --> H[prepend / append] F --> I[Node is visible] I --> J[Later: remove]
Creating Elements
The createElement method creates a new element node in memory. It does not appear on the page until you insert it.
// Create a new div element
const newDiv = document.createElement('div');
newDiv.textContent = 'Hello from created element!';
newDiv.className = 'created-box';
// The element exists in memory but is not visible yet
console.log('Created element:', newDiv);
console.log('Is it on the page?', document.body.contains(newDiv));
// Now insert it into the DOM
document.body.appendChild(newDiv);
console.log('Is it on the page now?', document.body.contains(newDiv));
Expected output: The first log shows the element exists. contains returns false before appending and true after.
Creating Text and Comment Nodes
Besides elements, you can create text and comment nodes explicitly.
// Create a text node
const textNode = document.createTextNode('This is plain text content');
console.log('Text node value:', textNode.nodeValue);
console.log('Text node type:', textNode.nodeType);
// Create a comment node
const commentNode = document.createComment('This section was added dynamically');
console.log('Comment text:', commentNode.nodeValue);
// Insert them into the DOM
const container = document.querySelector('.content');
container.appendChild(commentNode);
container.appendChild(textNode);
// Text nodes are useful when you want to
// insert text without creating an element wrapper
Expected output: The console shows the text content, node types, and comment text. The document shows the text rendered without an HTML wrapper.
Inserting at Exact Positions
Different insertion methods place nodes at different positions.
const list = document.querySelector('ul');
// Append at the end
const lastItem = document.createElement('li');
lastItem.textContent = 'Last item';
list.appendChild(lastItem);
// Insert before the first child
const firstItem = document.createElement('li');
firstItem.textContent = 'First item';
list.insertBefore(firstItem, list.firstChild);
// Insert before a specific element
const middleItem = document.createElement('li');
middleItem.textContent = 'Middle item';
list.insertBefore(middleItem, list.children[2]);
// Modern relative methods
const extraItem = document.createElement('li');
extraItem.textContent = 'Extra item';
// Insert after a specific element
list.children[1].after(extraItem);
// Insert before a specific element
list.children[0].before(document.createElement('li'));
console.log('Total items:', list.children.length);
Expected output: The list grows to include items at all specified positions. The final count reflects all insertions.
Removing Nodes
Removing nodes can be done directly or through the parent.
// Modern API: direct removal
const element = document.querySelector('.to-remove');
if (element) {
element.remove();
console.log('Element removed');
}
// Older API: removal through parent
const another = document.querySelector('.another-to-remove');
if (another && another.parentNode) {
another.parentNode.removeChild(another);
console.log('Another element removed');
}
// Clear all children from a container
const container = document.querySelector('.dynamic-content');
while (container.firstChild) {
container.removeChild(container.firstChild);
}
console.log('Container cleared:', container.children.length);
// Modern alternative: innerHTML = ''
// But this may cause memory leaks with attached event listeners
Expected output: Elements are removed from the DOM. The container's child count drops to zero.
Replacing Nodes
Replace an existing node with a new one using replaceChild or replaceWith.
const oldElement = document.querySelector('.old-widget');
const newElement = document.createElement('div');
newElement.textContent = 'New widget';
newElement.className = 'new-widget';
// Method 1: replaceChild (through parent)
if (oldElement.parentNode) {
oldElement.parentNode.replaceChild(newElement, oldElement);
}
// Method 2: replaceWith (direct)
// oldElement.replaceWith(newElement);
console.log('Is old element in DOM?', document.body.contains(oldElement));
console.log('Is new element in DOM?', document.body.contains(newElement));
// The old element is detached from the DOM
// but still exists in memory if referenced
Expected output: The new widget replaces the old one visually. The old element is no longer in the DOM but the variable still references it.
Efficient Bulk Insertion
Creating many nodes one by one causes multiple reflow calculations. Batch inserts for performance.
// Inefficient: creates 100 reflows
const container = document.getElementById('results');
// for (let i = 0; i < 100; i++) {
// const p = document.createElement('p');
// p.textContent = `Item ${i}`;
// container.appendChild(p);
// }
// Efficient: uses a document fragment (single reflow)
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
const p = document.createElement('p');
p.textContent = `Item ${i}`;
fragment.appendChild(p);
}
container.appendChild(fragment);
console.log('Inserted 100 items in one batch');
Expected output: The container shows all 100 items after a single reflow. The document fragment is an invisible temporary container that avoids multiple DOM updates.
Common Mistakes
- Creating a node but never inserting it —
createElementcreates a node in memory. If you do not insert it, it never appears and becomes garbage collected. - Removing a node while iterating a live collection — Using
getElementsByTagNameorchildrenwhile removing nodes modifies the collection and causes skipped elements. - Using innerHTML to clear content with attached listeners — Setting
innerHTML = ''removes elements but their event listeners may not be garbage collected if closures reference the elements. - Forgetting that insertBefore requires the parent —
insertBeforemust be called on the parent node, not the reference node. This is a common source of errors. - Creating duplicate IDs — When dynamically creating elements with IDs, ensure each ID is unique. Use class names or data attributes instead of IDs for repeated content.
Practice Questions
- What is the difference between removeChild and remove? removeChild is called on the parent node with the child as argument. remove is called directly on the element.
- Where does appendChild insert the new node? At the end of the parent's children, after the last child.
- Why use a document fragment for bulk inserts? The fragment is not part of the live DOM tree, so appending to it does not trigger reflow. Only the final appendChild of the fragment triggers a single reflow.
- Challenge: Implement a simple DOM recycling pool. Create 50 elements upfront and store them in an array. When content needs to be displayed, pull from the pool instead of creating new elements. When content is removed, return elements to the pool.
FAQ
Mini Project
Build an infinite scrolling list. Create a container div. Write a function that generates 20 list items with random text, wraps them in a document fragment, and appends them to the container. When the user scrolls near the bottom, load 20 more items. Use efficient node creation patterns to avoid jank. Include a "Clear" button that removes all items.
What's Next
Continue with Lesson 9: innerHTML vs DOM Methods to understand when to use innerHTML and when to use DOM manipulation APIs for security and performance.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro