Working with the DOM
The Document Object Model (DOM) is JavaScript’s gateway to HTML. Every web page you interact with is represented as a tree of objects that JavaScript can read and modify. This tutorial walks you through selecting elements, creating new content, handling events, and building interactive experiences.
Understanding the DOM
When a browser loads an HTML page, it parses the markup and builds a tree structure called the DOM. Each HTML tag becomes a node in this tree, with parent-child relationships reflecting the nesting in your HTML.
// The document object is your entry point to the DOM
console.log(document.title); // Page title
console.log(document.body); // The <body> element
console.log(document.location.href); // Current URL
Every element in the DOM is an object with properties you can read and methods you can call. Changing these properties updates the page in real-time.
Selecting Elements
Before you can work with elements, you need to find them. JavaScript provides several methods for selecting elements from the DOM.
getElementById and querySelector
The fastest way to get a single element is by its ID:
const header = document.getElementById('main-header');
console.log(header.textContent);
For more flexible selection, querySelector uses CSS selectors:
// Get the first matching element
const firstButton = document.querySelector('.btn');
// Get all matching elements
const allButtons = document.querySelectorAll('.btn');
querySelectorAll returns a NodeList, which you can loop through:
document.querySelectorAll('.menu-item').forEach(item => {
console.log(item.textContent);
});
Selecting Form Elements
Forms have special methods for accessing inputs:
const form = document.getElementById('my-form');
const username = form.elements.username;
const password = form.elements.password;
Creating and Inserting Elements
Building dynamic pages requires creating new elements and placing them in the DOM.
Creating Elements
Use document.createElement() to make new nodes:
const newParagraph = document.createElement('p');
newParagraph.textContent = 'Hello, world!';
newParagraph.className = 'highlight';
Inserting Elements
Once you have an element, insert it with these methods:
const container = document.getElementById('container');
// Add as the last child
container.appendChild(newParagraph);
// Insert before a specific child
const reference = container.querySelector('.some-element');
container.insertBefore(newParagraph, reference);
// Modern insertion methods (more flexible)
container.prepend(newParagraph); // Insert at start
container.before(newParagraph); // Insert before container
container.after(newParagraph); // Insert after container
Template Literals for HTML
For larger chunks of HTML, template literals work well:
const card = document.createElement('div');
card.className = 'card';
card.innerHTML = `
<h2>${title}</h2>
<p>${description}</p>
<button>Click me</button>
`;
document.body.appendChild(card);
Modifying Elements
Once you have a reference to an element, you can change its properties.
Changing Content
const element = document.getElementById('content');
// Replace all content
element.textContent = 'New text content';
// Or HTML content
element.innerHTML = '<strong>Bold</strong> and normal text';
Changing Attributes and Properties
const link = document.querySelector('a');
// Set attributes
link.setAttribute('href', 'https://example.com');
link.setAttribute('target', '_blank');
// Or use property syntax
link.href = 'https://example.com';
link.target = '_blank';
// Check attributes
if (link.hasAttribute('data-id')) {
console.log(link.dataset.id);
}
Working with Classes
const box = document.getElementById('box');
// Add classes
box.classList.add('active', 'highlighted');
// Remove classes
box.classList.remove('hidden');
// Toggle a class
box.classList.toggle('expanded');
// Check for class
if (box.classList.contains('active')) {
console.log('Box is active');
}
Styling
const element = document.getElementById('my-element');
// Direct style changes
element.style.color = 'blue';
element.style.backgroundColor = '#f0f0f0';
element.style.display = 'none';
// For complex styles, use getComputedStyle
const styles = getComputedStyle(element);
console.log(styles.fontSize);
Removing Elements
Clean up elements you no longer need:
const element = document.getElementById('to-remove');
// Remove from DOM
element.remove();
// Or the older method
element.parentNode.removeChild(element);
Handling Events
Events make pages interactive. JavaScript can respond to clicks, keypresses, form submissions, and more.
Adding Event Listeners
The addEventListener method attaches handlers to elements:
const button = document.getElementById('my-button');
button.addEventListener('click', function(event) {
console.log('Button clicked!');
console.log(event.target); // The element that was clicked
});
You can also use arrow functions:
button.addEventListener('click', (e) => {
e.preventDefault(); // Prevent default behavior
console.log('Clicked at:', e.clientX, e.clientY);
});
Common Events
// Mouse events
element.addEventListener('click', handler);
element.addEventListener('mouseenter', handler);
element.addEventListener('mouseleave', handler);
// Keyboard events
document.addEventListener('keydown', (e) => {
console.log('Key pressed:', e.key);
});
document.addEventListener('keyup', handler);
// Form events
form.addEventListener('submit', (e) => {
e.preventDefault(); // Stop page reload
// Process form data
});
input.addEventListener('input', (e) => {
console.log('Current value:', e.target.value);
});
input.addEventListener('change', (e) => {
console.log('Final value:', e.target.value);
});
// Document events
document.addEventListener('DOMContentLoaded', () => {
console.log('DOM is ready!');
});
window.addEventListener('load', () => {
console.log('Page fully loaded');
});
Event Delegation
Instead of adding listeners to each child, attach one to the parent:
const list = document.getElementById('my-list');
list.addEventListener('click', (e) => {
// Check if a list item was clicked
if (e.target.tagName === 'LI') {
console.log('List item clicked:', e.target.textContent);
}
});
This approach works even for dynamically added elements.
Removing Event Listeners
function handleClick() {
console.log('Clicked!');
}
button.addEventListener('click', handleClick);
// Later, remove it
button.removeEventListener('click', handleClick);
Working with Forms
Forms are central to most web applications. Here’s how to handle them:
const form = document.getElementById('registration-form');
form.addEventListener('submit', (e) => {
e.preventDefault();
// Get form data
const formData = new FormData(form);
const data = Object.fromEntries(formData);
console.log('Form data:', data);
// Or access individual fields
const email = form.elements.email.value;
const agreed = form.elements.terms.checked;
});
Input Validation
const input = document.getElementById('username');
input.addEventListener('blur', () => {
if (input.value.length < 3) {
input.setCustomValidity('Username must be at least 3 characters');
input.reportValidity();
} else {
input.setCustomValidity('');
}
});
Practical Example: Todo List
Let’s build a simple todo list to apply what we’ve learned:
const todoForm = document.getElementById('todo-form');
const todoInput = document.getElementById('todo-input');
const todoList = document.getElementById('todo-list');
todoForm.addEventListener('submit', (e) => {
e.preventDefault();
const text = todoInput.value.trim();
if (!text) return;
// Create todo item
const li = document.createElement('li');
li.innerHTML = `
<span>${text}</span>
<button class="delete-btn">×</button>
`;
// Delete handler
li.querySelector('.delete-btn').addEventListener('click', () => {
li.remove();
});
todoList.appendChild(li);
todoInput.value = '';
});
Summary
The DOM is your interface for building interactive web pages. Key takeaways:
- Use
getElementByIdandquerySelectorto find elements - Create elements with
document.createElement()and insert withappendChild,prepend, orinsertBefore - Modify content with
textContentandinnerHTML - Handle events with
addEventListener - Use event delegation for dynamic elements
With these fundamentals, you can build anything from simple interactive widgets to complex single-page applications.