Table of Contents
- Introduction to the DOM
- Selecting DOM Elements
- Modifying DOM Elements
- Creating and Removing Elements
- Styling DOM Elements
- Event Handling
- Traversing the DOM
- Best Practices
- Conclusion
- References
Introduction to the DOM
What is the DOM?
The DOM is a tree-like representation of a document (e.g., an HTML page). Every element, attribute, and piece of text in your HTML becomes a node in this tree. Think of it as a blueprint that JavaScript can read and modify.
For example, consider this simple HTML snippet:
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
</head>
<body>
<h1>Hello, DOM!</h1>
<p>This is a paragraph.</p>
</body>
</html>
The DOM tree for this HTML would look like:
Document
└── html
├── head
│ └── title
│ └── "My Page" (text node)
└── body
├── h1
│ └── "Hello, DOM!" (text node)
└── p
└── "This is a paragraph." (text node)
- Document: The root node of the tree.
- Elements: Nodes like
<html>,<head>, or<p>. - Text Nodes: Contain text (e.g., “Hello, DOM!”).
Selecting DOM Elements
Before manipulating elements, you need to select them. JavaScript provides several methods to target elements in the DOM.
1. getElementById()
Selects an element by its id attribute (unique in a document).
Example:
<div id="main-content">Hello World</div>
const mainContent = document.getElementById("main-content");
console.log(mainContent); // <div id="main-content">Hello World</div>
2. getElementsByClassName()
Selects all elements with a given class name, returning an HTMLCollection (live, ordered list of elements).
Example:
<ul>
<li class="item">Item 1</li>
<li class="item">Item 2</li>
</ul>
const items = document.getElementsByClassName("item");
console.log(items); // HTMLCollection(2) [li.item, li.item]
console.log(items[0]); // <li class="item">Item 1</li>
Note: HTMLCollections update automatically if the DOM changes (e.g., adding/removing elements with the class).
3. getElementsByTagName()
Selects all elements with a given tag name (e.g., div, p), returning an HTMLCollection.
Example:
<p>First paragraph</p>
<p>Second paragraph</p>
const paragraphs = document.getElementsByTagName("p");
console.log(paragraphs.length); // 2
4. querySelector()
Selects the first element matching a CSS selector (e.g., #id, .class, tag), returning a single element or null.
Example:
<div class="container">
<p class="text">Hello</p>
</div>
const text = document.querySelector(".container .text");
console.log(text); // <p class="text">Hello</p>
5. querySelectorAll()
Selects all elements matching a CSS selector, returning a NodeList (static list of nodes).
Example:
<ul>
<li>Apple</li>
<li>Banana</li>
<li>Cherry</li>
</ul>
const fruits = document.querySelectorAll("ul li");
console.log(fruits); // NodeList(3) [li, li, li]
Note: NodeLists are static (they don’t update when the DOM changes) unless you use getElementsBy*.
Modifying DOM Elements
Once you’ve selected an element, you can modify its content, attributes, or classes.
Updating Content
textContent
Sets/returns the text content of an element (ignores HTML tags, safer for user input).
Example:
<p id="greeting">Hello</p>
const greeting = document.getElementById("greeting");
greeting.textContent = "Hello, DOM Manipulation!";
// Result: <p id="greeting">Hello, DOM Manipulation!</p>
innerHTML
Sets/returns the HTML content of an element (parses HTML, useful for adding elements but risky with untrusted input due to XSS).
Example:
<div id="content"></div>
const content = document.getElementById("content");
content.innerHTML = "<h2>Welcome</h2><p>Learn DOM manipulation.</p>";
// Result: <div id="content"><h2>Welcome</h2><p>Learn DOM manipulation.</p></div>
Modifying Attributes
Use getAttribute(), setAttribute(), and removeAttribute() to interact with element attributes (e.g., src, href, disabled).
Example:
<img id="logo" src="old-logo.png" alt="Old Logo">
const logo = document.getElementById("logo");
// Get attribute
console.log(logo.getAttribute("src")); // "old-logo.png"
// Set attribute
logo.setAttribute("src", "new-logo.png");
logo.setAttribute("alt", "New Logo");
// Remove attribute
logo.removeAttribute("alt");
Managing Classes
The classList property lets you add, remove, toggle, or check for classes on an element.
Example:
<div id="box" class="active">Box</div>
const box = document.getElementById("box");
// Add a class
box.classList.add("large"); // <div id="box" class="active large">Box</div>
// Remove a class
box.classList.remove("active"); // <div id="box" class="large">Box</div>
// Toggle a class (add if missing, remove if present)
box.classList.toggle("hidden"); // <div id="box" class="large hidden">Box</div>
// Check if a class exists
console.log(box.classList.contains("large")); // true
Creating and Removing Elements
You can dynamically create new elements or remove existing ones from the DOM.
Creating Elements
Use document.createElement(tagName) to create a new element, then append it to the DOM with methods like appendChild() or prepend().
Example: Create and append a <div>
// Step 1: Create a new div element
const newDiv = document.createElement("div");
// Step 2: Add content or attributes
newDiv.textContent = "New Div";
newDiv.classList.add("info");
// Step 3: Append to the body (or another parent element)
document.body.appendChild(newDiv);
Result:
<body>
<!-- Existing content -->
<div class="info">New Div</div>
</body>
Removing Elements
Use removeChild() (on the parent) or remove() (on the element itself) to delete elements.
Example:
<ul id="list">
<li>Item to Remove</li>
</ul>
const list = document.getElementById("list");
const itemToRemove = list.firstElementChild;
// Method 1: Remove via parent
list.removeChild(itemToRemove);
// Method 2: Remove directly (modern browsers)
itemToRemove.remove();
Styling DOM Elements
You can modify inline styles or read computed styles of elements.
Inline Styles (element.style)
Access or set inline CSS styles using the style property (use camelCase for CSS properties, e.g., fontSize instead of font-size).
Example:
<p id="text">Hello</p>
const text = document.getElementById("text");
text.style.color = "blue";
text.style.fontSize = "24px";
text.style.backgroundColor = "#f0f0f0";
Result: The text will be blue, 24px, with a light gray background.
Computed Styles (getComputedStyle())
Retrieve the computed CSS values of an element (includes styles from stylesheets, not just inline).
Example:
<style>
#box { color: red; font-size: 16px; }
</style>
<div id="box" style="background: yellow;">Box</div>
const box = document.getElementById("box");
const computedStyle = getComputedStyle(box);
console.log(computedStyle.color); // "rgb(255, 0, 0)" (red)
console.log(computedStyle.fontSize); // "16px"
console.log(computedStyle.backgroundColor); // "rgb(255, 255, 0)" (yellow)
Event Handling
Events (e.g., clicks, form submissions) trigger actions in your code. Use addEventListener() to attach event handlers.
Basic Syntax
element.addEventListener(eventType, handlerFunction);
Common Events
click: Triggered on mouse click.mouseover: Triggered when the mouse hovers over an element.submit: Triggered when a form is submitted.keydown: Triggered when a key is pressed.
Example: Click Event
<button id="btn">Click Me</button>
<p id="output"></p>
const btn = document.getElementById("btn");
const output = document.getElementById("output");
btn.addEventListener("click", () => {
output.textContent = "Button clicked!";
});
Event Object
The handler function receives an event object with details about the event (e.g., target (the element clicked), type (event type)).
Example:
btn.addEventListener("click", (event) => {
console.log(event.target); // <button id="btn">Click Me</button>
console.log(event.type); // "click"
});
Removing Event Listeners
Use removeEventListener() to detach a handler (requires a named function, not an arrow function).
Example:
function handleClick() {
output.textContent = "Clicked!";
}
btn.addEventListener("click", handleClick);
// Later, remove the listener
btn.removeEventListener("click", handleClick);
Traversing the DOM
Traverse the DOM tree to navigate between parent, child, and sibling elements.
Parent Nodes
parentNode: Returns the parent node (can be any node type, e.g., text, comment).parentElement: Returns the parent element node (ignores non-element nodes).
Example:
<div id="parent">
<p id="child">Child</p>
</div>
const child = document.getElementById("child");
console.log(child.parentNode); // <div id="parent">...</div>
console.log(child.parentElement); // <div id="parent">...</div>
Child Nodes
childNodes: Returns all child nodes (including text nodes, comments).children: Returns only child element nodes.
Example:
<ul id="list">
<li>Item 1</li>
<li>Item 2</li>
</ul>
const list = document.getElementById("list");
console.log(list.childNodes); // NodeList(5) [text, li, text, li, text] (whitespace is text nodes)
console.log(list.children); // HTMLCollection(2) [li, li] (only elements)
Sibling Nodes
previousSibling/nextSibling: Returns the previous/next sibling node (including text nodes).previousElementSibling/nextElementSibling: Returns the previous/next sibling element.
Example:
<p>First</p>
<p id="middle">Middle</p>
<p>Last</p>
const middle = document.getElementById("middle");
console.log(middle.previousElementSibling); // <p>First</p>
console.log(middle.nextElementSibling); // <p>Last</p>
Best Practices
- Avoid Inline Event Handlers: Use
addEventListener()instead ofonclickattributes for cleaner, more maintainable code. - Minimize DOM Manipulation: DOM updates are slow. Batch changes (e.g., use
documentFragmentfor multiple appends). - Use Efficient Selectors: Prefer
getElementById(fastest) over complexquerySelectorchains. - Debounce/Throttle Frequent Events: For events like
resizeorscroll, limit how often handlers run (e.g., with Lodash’sdebounce). - Clean Up Event Listeners: Remove listeners when elements are removed to prevent memory leaks.
Conclusion
DOM manipulation is a cornerstone of dynamic web development. By mastering element selection, modification, event handling, and traversal, you can build interactive, responsive websites. Practice with small projects (e.g., to-do lists, calculators) to reinforce these skills. The DOM API is vast, but with these fundamentals, you’ll be well-equipped to explore advanced techniques!