Mastering the DOM: Select, Style, Create & Remove Elements with JavaScript
A practical, example-driven guide to understanding the DOM, manipulating elements, changing styles dynamically, and creating/removing nodes—step by st

TL;DR
The DOM is a tree of nodes representing your HTML.
You can select nodes with
querySelector, modify content withtextContent/innerHTML, style them withstyle/classList, and create/remove nodes withcreateElement,append,remove.Bonus: before/after demo shows what changes on the page.
1) What is the DOM?
DOM (Document Object Model) = a tree-like representation of your HTML in memory. Every tag becomes a node (element node, text node, etc.). JavaScript can traverse this tree, find nodes, read/change attributes, styles, and even create or delete nodes.
Mental model:
documentis the root.<html>→<head>and<body>.Inside
<body>you’ll have nested elements (div, p, img, ul > li, etc.).
Why it matters:
- Any interactive feature (open menus, modals, form validation, dynamic lists) depends on DOM manipulation.
2) Selecting Elements
Common Selectors
<ul id="todo-list">
<li class="todo">Buy milk</li>
<li class="todo">Study DOM</li>
</ul>
<button id="add-btn">Add</button>
// Single element
const list = document.getElementById('todo-list'); // by id
const firstTodo = document.querySelector('.todo'); // CSS selector
// Multiple elements (NodeList)
const allTodos = document.querySelectorAll('.todo'); // CSS selector all
// Live HTMLCollection (updates when DOM changes)
const lis = document.getElementsByTagName('li');
// Traversal helpers
firstTodo.parentElement; // <ul>
list.children; // HTMLCollection of <li>
list.firstElementChild; // first <li>
list.lastElementChild; // last <li>
Tip: Prefer querySelector/querySelectorAll for flexible CSS-style selecting.
3) Reading & Modifying Content
<p id="message">Hello, world!</p>
const msg = document.getElementById('message');
// Read text
console.log(msg.textContent); // "Hello, world!"
// Change text (safe: no HTML parsing)
msg.textContent = 'Updated via JavaScript';
// Inject HTML (⚠️ avoid with user input)
msg.innerHTML = '<strong>Bold move!</strong>';
Attributes & data-attributes
<img id="avatar" src="/img/guest.png" alt="Guest" data-user-id="42">
const avatar = document.getElementById('avatar');
avatar.getAttribute('src'); // "/img/guest.png"
avatar.setAttribute('alt', 'Profile');
avatar.dataset.userId; // "42"
avatar.dataset.role = 'admin';
4) Changing Styles Dynamically
Inline styles (quick tweaks)
msg.style.color = 'rebeccapurple';
msg.style.backgroundColor = '#f0f0ff';
msg.style.padding = '8px 12px';
Class-based styling (recommended)
/* styles.css */
.highlight { background: #fff3cd; color: #664d03; padding: 8px; border-radius: 6px; }
.hidden { display: none; }
msg.classList.add('highlight');
msg.classList.toggle('hidden'); // hides/shows
msg.classList.remove('highlight');
msg.classList.contains('hidden'); // boolean
Computed styles (read-only)
const styles = getComputedStyle(msg);
console.log(styles.marginTop, styles.fontSize);
5) Creating & Removing Elements
Creating, appending, inserting
const li = document.createElement('li');
li.className = 'todo';
li.textContent = 'Write a blog on DOM';
const list = document.getElementById('todo-list');
list.append(li); // append as last child
// Insert before first item
list.insertBefore(li, list.firstElementChild);
// Add HTML chunks (use carefully)
list.insertAdjacentHTML('beforeend', '<li class="todo">Ship it!</li>');
Replacing & removing
// Replace a node
const newP = document.createElement('p');
newP.textContent = 'This replaced the message.';
msg.replaceWith(newP);
// Remove a node
newP.remove();
// Or via parent
// list.removeChild(list.lastElementChild);
6) Events + DOM Manipulation (Practical Demo)
<input id="todo-input" placeholder="New task..." />
<button id="add-btn">Add</button>
<ul id="todo-list"></ul>
const input = document.getElementById('todo-input');
const addBtn = document.getElementById('add-btn');
const list = document.getElementById('todo-list');
addBtn.addEventListener('click', () => {
const text = input.value.trim();
if (!text) return;
const li = document.createElement('li');
li.className = 'todo';
li.textContent = text;
// remove on click
li.addEventListener('click', () => li.remove());
list.append(li);
input.value = '';
});
// Enter key adds too
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter') addBtn.click();
});
What’s happening:
You create elements from input.
You attach event handlers to new elements.
Clicking a task removes it → tiny “to-do” app in ~20 lines.
7) Before & After: Dynamic Page Example
Before (HTML only)
<div class="card">
<h2 id="title">Welcome</h2>
<p id="desc">This is a static description.</p>
<button id="cta">Surprise me</button>
</div>
After (JavaScript applies changes)
const title = document.getElementById('title');
const desc = document.getElementById('desc');
const cta = document.getElementById('cta');
cta.addEventListener('click', () => {
title.textContent = '🎉 DOM Magic!';
desc.textContent = 'This text and styles were updated via JavaScript.';
document.querySelector('.card').classList.add('highlight');
// Add a confetti note
const note = document.createElement('p');
note.textContent = '✨ New element inserted dynamically!';
note.className = 'highlight';
cta.insertAdjacentElement('afterend', note);
});
Result: The card’s title and description change, a new paragraph appears, and styles update—classic “before/after” DOM manipulation.
8) Performance & Best Practices
Batch DOM writes: frequent layout thrashing is slow. Combine edits: set classes rather than many inline styles, or use a DocumentFragment for many inserts.
Event delegation: attach one listener to a parent instead of many children.
list.addEventListener('click', (e) => { if (e.target.matches('.todo')) e.target.remove(); });Avoid
innerHTMLwith untrusted data: prevents XSS. PrefertextContent, or sanitize.Prefer CSS for visual rules: JS toggles classes; CSS defines appearance.
9) Quick Reference (Cheat Sheet)
Select:
querySelector,querySelectorAll,getElementByIdContent:
textContent,innerHTMLStyle:
element.style.*,classList.add/remove/toggle/containsCreate:
createElement,append,prepend,insertBefore,insertAdjacentHTML/ElementRemove:
remove,removeChildEvents:
addEventListener,event delegationTraversal:
parentElement,children,firstElementChild,nextElementSibling