The DOM (Document Object Model) is the live, tree-shaped representation of a webpage that JavaScript can read and change in real time. This lesson covers selecting elements with getElementById and querySelector, updating text and styles, adding and removing CSS classes, creating and appending new elements, and traversing between related nodes.
1JS DOM Intro | JavaScript Tutorial - In-Depth Guide Part 1
Welcome to the DOM (Document Object Model). The DOM is the bridge between your static HTML and your dynamic JavaScript. It represents your webpage as a tree of objects that you can manipulate in real-time.
// The DOM: Bringing HTML to LifeThe DOM API
2JS DOM Intro | JavaScript Tutorial - In-Depth Guide Part 2
To change an element, you first need to SELECT it. The 'document' object is your starting point. Use getElementById to target a unique element by its ID.
const title = document.getElementById('main-title');DOM Selection
3JS DOM Intro | JavaScript Tutorial - In-Depth Guide Part 3
querySelector is the modern way to select. It uses CSS selector syntax (.class, #id, tag) to find the first matching element in the tree.
const button = document.querySelector('.btn-primary');querySelector
4JS DOM Intro | JavaScript Tutorial - In-Depth Guide Part 4
Once you have an element, you can change its text using the .textContent property. This update happens instantly in the browser.
title.textContent = 'Welcome to the Future';Text Content
5JS DOM Intro | JavaScript Tutorial - In-Depth Guide Part 5
You can even change CSS styles directly through the .style property. Note that CSS properties with hyphens (background-color) become camelCase in JS.
title.style.color = 'cyan';
title.style.fontSize = '40px';Live Styling
6JS DOM Intro | JavaScript Tutorial - In-Depth Guide Part 6
Adding or removing classes is safer than changing styles directly. Use the .classList API to manage your element's states.
button.classList.add('active');
button.classList.remove('hidden');Class Manipulation
7JS DOM Intro | JavaScript Tutorial - In-Depth Guide Part 7
Watch the render. See how selecting an element allows you to override the original HTML and CSS, transforming the page dynamically.
Live Render
8JS DOM Intro | JavaScript Tutorial - In-Depth Guide Part 8
Creating elements: Use document.createElement to build a new node in memory. It won't appear on the page until you 'append' it.
const newDiv = document.createElement('div');
newDiv.textContent = 'New Node!';
document.body.appendChild(newDiv);Creating Elements
9JS DOM Intro | JavaScript Tutorial - In-Depth Guide Part 9
The .innerHTML property allows you to inject raw HTML strings. Be careful! It can be a security risk if you're handling user-generated content.
const container = document.querySelector('#box');
container.innerHTML = '<strong>Bold text</strong>';innerHTML Injection
10JS DOM Intro | JavaScript Tutorial - In-Depth Guide Part 10
Traversing the DOM: You can navigate between elements using properties like .parentNode, .children, and .nextElementSibling.
const parent = button.parentNode;
const firstChild = container.children[0];DOM Traversal
11JS DOM Intro | JavaScript Tutorial - In-Depth Guide Part 11
You've mastered the interface between logic and layout. You can now surgically modify any part of a webpage on the fly.
console.log('DOM Access: Authorized');DOM Authorized
12JS DOM Intro | JavaScript Tutorial - In-Depth Guide Part 12
DOM mastery achieved! Now let's learn how to react to user actions with Events.
On to Events
13Step-by-Step Breakdown
Welcome to the DOM (Document Object Model). The DOM is the bridge between your static HTML and your dynamic JavaScript. It represents your webpage as a tree of objects that you can manipulate in real-time.
To change an element, you first need to SELECT it. The 'document' object is your starting point. Use getElementById to target a unique element by its ID.
querySelector is the modern way to select. It uses CSS selector syntax (.class, #id, tag) to find the first matching element in the tree.
Checkpoint: Which method should you use to select a single element using its CSS class name?
- āgetElementById
- āquerySelector
Once you have an element, you can change its text using the .textContent property. This update happens instantly in the browser.
You can even change CSS styles directly through the .style property. Note that CSS properties with hyphens (background-color) become camelCase in JS.
Adding or removing classes is safer than changing styles directly. Use the .classList API to manage your element's states.
Watch the render. See how selecting an element allows you to override the original HTML and CSS, transforming the page dynamically.
Checkpoint: How would you write the CSS property 'background-color' when accessing it through 'el.style' in JavaScript?
- ābackground-color
- ābackgroundColor (camelCase)
Creating elements: Use document.createElement to build a new node in memory. It won't appear on the page until you 'append' it.
The .innerHTML property allows you to inject raw HTML strings. Be careful! It can be a security risk if you're handling user-generated content.
Traversing the DOM: You can navigate between elements using properties like .parentNode, .children, and .nextElementSibling.
You've mastered the interface between logic and layout. You can now surgically modify any part of a webpage on the fly.
Checkpoint: What happens to an element created with 'document.createElement' before you call 'appendChild'?
- āIt appears at the top of the page
- āIt exists only in memory (invisible)
DOM mastery achieved! Now let's learn how to react to user actions with Events.
Level Up š
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Dynamically Inserted Content Needs an Accessible Live Region to Be Announced
Appending a new error message or notification to the DOM with appendChild() or innerHTML doesn't automatically get announced by a screen reader ā wrap the container in aria-live="polite" (or "assertive" for urgent messages) so assistive technology picks up the change the moment it happens.
<div aria-live="polite" id="status-region"></div>SEO Implications
- 1
Content Injected Purely via innerHTML After Load Can Be Missed by Crawlers
If key page content only exists after JavaScript runs document.createElement()/appendChild() or sets innerHTML client-side, search engines that don't fully execute your scripts (or that time out before your JS finishes) may index a page missing that content ā favor server-side rendering or static generation for anything crucial to SEO.
Best Practices
Prefer textContent Over innerHTML for Plain Text
Setting textContent treats the value as plain text and automatically escapes any HTML-like characters, so there's no risk of accidentally executing injected markup. Only use innerHTML when you specifically need to render actual HTML, and never with unsanitized user input.
Batch DOM Changes to Avoid Repeated Layout Recalculation
Every time you change something that affects layout (like appending elements one at a time in a loop), the browser may need to recalculate layout ('reflow'). Build up changes with a DocumentFragment or by modifying an element's HTML once, then append it, instead of touching the live DOM repeatedly.
Frequent Bugs
Setting innerHTML with unsanitized user input allows a cross-site scripting (XSS) attack.
innerHTML parses and executes any HTML ā including <script> tags or event handler attributes ā in whatever string you assign to it. Use textContent for plain text, or sanitize the HTML with a trusted library (like DOMPurify) before ever assigning untrusted content to innerHTML.
Real-World Examples
Toggling a Custom Dropdown's Visibility with classList
A navigation dropdown needed to show and hide its menu on click without directly manipulating inline styles, so the visual state could stay driven entirely by CSS classes.
const dropdown = document.querySelector('.dropdown-menu');
const toggleBtn = document.querySelector('.dropdown-toggle');
toggleBtn.addEventListener('click', () => {
dropdown.classList.toggle('is-open');
});