JavaScript DOM
Learn how JavaScript interacts with HTML using the Document Object Model. Master element selection, content manipulation, attributes, styles, classes, element creation, traversal, forms, collections, and dynamic web page updates.
Introduction
HTML creates the structure of a web page, CSS controls its appearance, and JavaScript adds behavior. However, JavaScript needs a way to find, read, change, create, and remove HTML elements. The Document Object Model, commonly called the DOM, provides this connection.
The DOM represents an HTML document as a tree of JavaScript objects. Every heading, paragraph, button, image, form, attribute, and text value becomes part of this object structure.
Using the DOM, JavaScript can change text, update images, modify styles, add or remove CSS classes, create new elements, delete existing elements, read form values, build dynamic interfaces, and much more.
- What the Document Object Model is.
- Why JavaScript needs the DOM.
- How browsers convert HTML into a DOM tree.
- What DOM nodes are.
- The different types of DOM nodes.
- What the document object represents.
- How to select HTML elements.
- How getElementById() works.
- How getElementsByClassName() works.
- How getElementsByTagName() works.
- How querySelector() works.
- How querySelectorAll() works.
- How to use CSS selectors in JavaScript.
- How to read and change text content.
- The difference between textContent, innerText, and innerHTML.
- How to read and modify attributes.
- How to work with custom data attributes.
- How to change inline styles.
- How to read computed styles.
- How to add, remove, toggle, check, and replace CSS classes.
- How to create new HTML elements.
- How to insert elements into the document.
- How to remove elements.
- How to replace elements.
- How to clone elements.
- How to navigate between parent, child, and sibling elements.
- How closest() and matches() work.
- The difference between HTMLCollection and NodeList.
- How to loop through selected elements.
- How to work with forms and input elements.
- How to read element dimensions.
- How to find an element position.
- How to scroll elements into view.
- How script placement affects DOM access.
- How to build a complete dynamic DOM application.
What is the DOM?
DOM stands for Document Object Model. It is a programming interface created by the browser that represents an HTML document as a structured tree of objects.
The word Document refers to the loaded web page. Object means that parts of the document are represented as programmable objects. Model means that these objects are organized into a structured representation.
D O M
D → Document
The HTML web page
O → Object
HTML elements become objects
M → Model
Objects are organized
in a tree structure<h1 id="title">
Welcome
</h1>
<p>
Learn JavaScript DOM.
</p>const title =
document.getElementById(
'title'
);
console.log(title);Why Do We Need the DOM?
Without the DOM, JavaScript would not have a standard way to interact with the visible HTML document. The DOM gives JavaScript access to page structure and content.
Find Elements
Select headings, buttons, forms, images, cards, and other elements.
Change Content
Update text, HTML content, labels, messages, and displayed values.
Change Appearance
Modify styles and CSS classes dynamically.
Create Elements
Generate cards, list items, notifications, tables, and other content.
Remove Elements
Delete elements that are no longer needed.
Work with Forms
Read and update input, checkbox, radio, and select values.
Build Interfaces
Create menus, tabs, modals, accordions, and dashboards.
Update Pages
Change the page without reloading the entire document.
Display Data
Convert JavaScript data into visible HTML content.
Add Interactivity
Combine DOM manipulation with events to respond to users.
Real-World Analogy
Think of an HTML document as a house and the DOM as a detailed map of that house. JavaScript uses the map to locate and modify individual parts.
HTML WEB PAGE
HOUSE
│
▼
┌──────────────────────────────┐
│ ROOM │
│ │
│ ┌────────┐ ┌──────────┐ │
│ │ TABLE │ │ CHAIR │ │
│ └────────┘ └──────────┘ │
│ │
│ ┌──────────────────────┐ │
│ │ WINDOW │ │
│ └──────────────────────┘ │
└──────────────────────────────┘
DOM MAP
document
│
└── room
│
├── table
│
├── chair
│
└── window
JAVASCRIPT
Find the chair
│
▼
Change its appearance
│
▼
Move or remove itHow the DOM Works
When a browser loads an HTML file, it reads the HTML source code and converts it into a DOM tree. JavaScript then interacts with this tree rather than directly editing the original HTML file.
HTML FILE
index.html
│
▼
BROWSER READS HTML
│
▼
HTML IS PARSED
│
▼
DOM TREE IS CREATED
│
▼
JAVASCRIPT ACCESSES DOM
│
├── Find Elements
│
├── Read Content
│
├── Change Content
│
├── Change Styles
│
├── Create Elements
│
└── Remove Elements
│
▼
VISIBLE PAGE UPDATES- The HTML file contains source code.
- The browser parses the HTML.
- The browser creates the DOM.
- JavaScript works with the DOM representation.
- DOM changes update the currently displayed page.
- Changing the DOM does not automatically rewrite the original HTML file.
HTML to DOM Tree
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
</head>
<body>
<h1>Welcome</h1>
<p>
Learn JavaScript.
</p>
</body>
</html>document
│
└── html
│
├── head
│ │
│ └── title
│ │
│ └── "My Page"
│
└── body
│
├── h1
│ │
│ └── "Welcome"
│
└── p
│
└── "Learn JavaScript."The DOM has a hierarchical structure. Elements can contain other elements, and these relationships are described using terms such as parent, child, and sibling.
DOM Nodes
Everything in the DOM tree is represented as a node. Elements, text, comments, and the document itself are different types of nodes.
<p id="message">
Hello World
</p>ELEMENT NODE
<p id="message">
│
▼
TEXT NODE
"Hello World"
The id attribute belongs
to the element.Types of DOM Nodes
Document Node
Represents the entire HTML document.
Element Node
Represents HTML elements such as div, p, button, and input.
Text Node
Represents text inside an HTML element.
Comment Node
Represents an HTML comment.
Attribute Data
Represents information associated with element attributes.
<!-- Comment Node -->
<section>
<h2>
DOM Nodes
</h2>
</section>DOCUMENT NODE
│
├── COMMENT NODE
│
└── ELEMENT NODE
│
└── section
│
└── ELEMENT NODE
│
└── h2
│
└── TEXT NODE
│
└── "DOM Nodes"The document Object
The document object represents the currently loaded HTML document. It is the main entry point for accessing and manipulating the DOM.
console.log(document);The document object provides properties and methods for finding elements, creating elements, reading document information, and modifying the page.
console.log(
document.title
);
console.log(
document.URL
);
console.log(
document.body
);
console.log(
document.head
);Accessing the Document
<!DOCTYPE html>
<html>
<head>
<title>DOM Course</title>
</head>
<body>
<h1>JavaScript DOM</h1>
</body>
</html>console.log(
document.title
);
console.log(
document.documentElement
);
console.log(
document.head
);
console.log(
document.body
);Selecting Elements
Before JavaScript can modify an HTML element, it usually needs to select that element. The document object provides several methods for finding elements.
document
│
├── getElementById()
│
├── getElementsByClassName()
│
├── getElementsByTagName()
│
├── querySelector()
│
└── querySelectorAll()getElementById()
The getElementById() method selects an element using its id attribute. Since an id should be unique within a document, this method returns one element or null.
<h1 id="title">
JavaScript DOM
</h1>const title =
document.getElementById(
'title'
);
console.log(title);const element =
document.getElementById(
'unknown'
);
console.log(element);getElementsByClassName()
The getElementsByClassName() method selects all elements containing a specified class and returns a live HTMLCollection.
<p class="message">First</p>
<p class="message">Second</p>
<p class="message">Third</p>const messages =
document.getElementsByClassName(
'message'
);
console.log(messages);
console.log(
messages.length
);const messages =
document.getElementsByClassName(
'message'
);
console.log(
messages[0]
);
console.log(
messages[1]
);getElementsByTagName()
The getElementsByTagName() method selects elements by their HTML tag name and returns a live HTMLCollection.
<p>Paragraph One</p>
<p>Paragraph Two</p>
<p>Paragraph Three</p>const paragraphs =
document.getElementsByTagName(
'p'
);
console.log(
paragraphs.length
);querySelector()
The querySelector() method accepts a CSS selector and returns the first matching element. If no element matches, it returns null.
<h1 id="title">
DOM Course
</h1>
<p class="message">
First Message
</p>
<p class="message">
Second Message
</p>const title =
document.querySelector(
'#title'
);
const message =
document.querySelector(
'.message'
);
const paragraph =
document.querySelector(
'p'
);
console.log(title);
console.log(message);
console.log(paragraph);- It accepts any valid CSS selector.
- It returns only the first matching element.
- It returns null when no match exists.
- Use # for an ID selector.
- Use . for a class selector.
- Use the tag name for an element selector.
querySelectorAll()
The querySelectorAll() method accepts a CSS selector and returns a static NodeList containing all matching elements.
<p class="message">One</p>
<p class="message">Two</p>
<p class="message">Three</p>const messages =
document.querySelectorAll(
'.message'
);
console.log(messages);
console.log(
messages.length
);const messages =
document.querySelectorAll(
'.message'
);
messages.forEach(
function (message) {
console.log(
message.textContent
);
}
);Selection Methods Comparison
Method
────────────────────────────────────────────
getElementById()
Selector:
ID value without #
Returns:
Single Element or null
getElementsByClassName()
Selector:
Class name without .
Returns:
Live HTMLCollection
getElementsByTagName()
Selector:
Tag name
Returns:
Live HTMLCollection
querySelector()
Selector:
Any CSS selector
Returns:
First Element or null
querySelectorAll()
Selector:
Any CSS selector
Returns:
Static NodeListCSS Selectors in JavaScript
querySelector() and querySelectorAll() support CSS selectors, making them flexible for selecting elements based on IDs, classes, attributes, relationships, and other conditions.
// ID
document.querySelector(
'#title'
);
// Class
document.querySelector(
'.card'
);
// Element
document.querySelector(
'button'
);
// Attribute
document.querySelector(
'[data-id]'
);
// Specific attribute value
document.querySelector(
'[type="email"]'
);
// Descendant
document.querySelector(
'.card p'
);
// Direct child
document.querySelector(
'.menu > li'
);
// Multiple selectors
document.querySelectorAll(
'h1, h2, h3'
);
// Pseudo-class
document.querySelector(
'li:first-child'
);Changing HTML Content
After selecting an element, JavaScript can read or change its content using properties such as textContent, innerText, and innerHTML.
textContent
The textContent property reads or replaces the text content of an element and its descendants.
<h1 id="title">
Old Title
</h1>const title =
document.getElementById(
'title'
);
title.textContent =
'JavaScript DOM';const title =
document.getElementById(
'title'
);
console.log(
title.textContent
);innerText
The innerText property represents the rendered visible text of an element. It considers styling and layout when determining visible text.
<div id="box">
Visible Text
<span style="display: none;">
Hidden Text
</span>
</div>const box =
document.getElementById(
'box'
);
console.log(
box.textContent
);
console.log(
box.innerText
);textContent includes text from hidden descendants, while innerText focuses on rendered visible text.
innerHTML
The innerHTML property reads or replaces the HTML markup inside an element.
<div id="container">
Original Content
</div>const container =
document.getElementById(
'container'
);
container.innerHTML = `
<h2>New Heading</h2>
<p>
New paragraph content.
</p>
`;- innerHTML parses strings as HTML.
- Do not insert untrusted user input directly with innerHTML.
- Unsafe HTML insertion can create security vulnerabilities.
- Use textContent when you only need plain text.
- Use createElement() when building structured content safely.
Content Properties Comparison
textContent
✓ Reads text
✓ Writes plain text
✓ Includes hidden text
✓ Does not parse HTML
innerText
✓ Reads rendered text
✓ Writes plain text
✓ Considers visibility
✓ May trigger layout calculation
innerHTML
✓ Reads HTML markup
✓ Writes HTML markup
✓ Parses HTML strings
⚠ Requires care with untrusted contentReading Element Content
<article id="article">
<h2>DOM Basics</h2>
<p>
Learn the Document Object Model.
</p>
</article>const article =
document.getElementById(
'article'
);
console.log(
article.textContent
);
console.log(
article.innerText
);
console.log(
article.innerHTML
);Changing Attributes
HTML elements can contain attributes such as id, class, src, href, title, alt, disabled, and data attributes. JavaScript can read, create, update, and remove these attributes.
getAttribute()
<a
id="website"
href="https://example.com"
title="Visit Website"
>
Visit
</a>const website =
document.getElementById(
'website'
);
console.log(
website.getAttribute(
'href'
)
);
console.log(
website.getAttribute(
'title'
)
);setAttribute()
const image =
document.querySelector(
'#profileImage'
);
image.setAttribute(
'src',
'profile.jpg'
);
image.setAttribute(
'alt',
'User Profile'
);hasAttribute()
The hasAttribute() method checks whether an element contains a specified attribute.
const input =
document.querySelector(
'input'
);
console.log(
input.hasAttribute(
'required'
)
);removeAttribute()
<button
id="submitButton"
disabled
>
Submit
</button>const button =
document.getElementById(
'submitButton'
);
button.removeAttribute(
'disabled'
);Direct Attribute Properties
Many common HTML attributes can also be accessed through element properties.
const image =
document.querySelector(
'img'
);
image.src =
'new-image.jpg';
image.alt =
'New Image';
const link =
document.querySelector(
'a'
);
link.href =
'https://example.com';
const input =
document.querySelector(
'input'
);
input.disabled =
true;Data Attributes
Custom data attributes store additional information directly on HTML elements. Their names begin with data-.
<article
id="course"
data-course-id="101"
data-category="javascript"
data-level="beginner"
>
JavaScript Course
</article>dataset
The dataset property provides convenient access to data attributes. Hyphenated names are converted into camelCase property names.
const course =
document.getElementById(
'course'
);
console.log(
course.dataset.courseId
);
console.log(
course.dataset.category
);
console.log(
course.dataset.level
);const course =
document.getElementById(
'course'
);
course.dataset.level =
'intermediate';
course.dataset.status =
'active';HTML
data-course-id="101"
│
▼
JavaScript
element.dataset.courseId
HTML
data-user-role="admin"
│
▼
JavaScript
element.dataset.userRoleChanging Styles
JavaScript can modify an element’s inline CSS styles using the style property.
The style Property
<div id="box">
Hello DOM
</div>const box =
document.getElementById(
'box'
);
box.style.color =
'white';
box.style.backgroundColor =
'purple';
box.style.padding =
'20px';
box.style.borderRadius =
'10px';CSS Property Names
CSS properties containing hyphens are normally written in camelCase when accessed through the JavaScript style object.
CSS
background-color
JavaScript
backgroundColor
CSS
font-size
JavaScript
fontSize
CSS
border-radius
JavaScript
borderRadius
CSS
margin-top
JavaScript
marginTopMultiple Inline Styles
const card =
document.querySelector(
'.card'
);
Object.assign(
card.style,
{
padding: '24px',
borderRadius: '12px',
backgroundColor: '#222',
color: 'white'
}
);- The style property is useful for dynamic values.
- CSS classes are usually better for reusable visual states.
- Keep complex styling in CSS files.
- Use classList to activate or deactivate those styles.
Reading Computed Styles
The style property mainly represents inline styles. To read the final style applied after CSS rules are calculated, use getComputedStyle().
const box =
document.querySelector(
'.box'
);
const styles =
getComputedStyle(box);
console.log(
styles.backgroundColor
);
console.log(
styles.fontSize
);Working with CSS Classes
CSS classes provide a clean way to define visual states. JavaScript can then add, remove, toggle, check, or replace those classes.
className
<div
id="box"
class="card active"
>
Content
</div>const box =
document.getElementById(
'box'
);
console.log(
box.className
);- Assigning className replaces existing classes.
- Use classList when changing individual classes.
- classList is usually safer for dynamic interfaces.
classList
The classList property provides methods for managing individual CSS classes without replacing the entire class attribute.
const box =
document.querySelector(
'.box'
);
console.log(
box.classList
);classList.add()
const box =
document.querySelector(
'.box'
);
box.classList.add(
'active'
);
box.classList.add(
'highlighted',
'large'
);classList.remove()
const box =
document.querySelector(
'.box'
);
box.classList.remove(
'active'
);
box.classList.remove(
'highlighted',
'large'
);classList.toggle()
The toggle() method adds a class when it is missing and removes it when it already exists.
const menu =
document.querySelector(
'.menu'
);
menu.classList.toggle(
'open'
);Class Missing
menu
│
▼
toggle('open')
│
▼
menu open
Class Exists
menu open
│
▼
toggle('open')
│
▼
menuclassList.contains()
const menu =
document.querySelector(
'.menu'
);
const isOpen =
menu.classList.contains(
'open'
);
console.log(isOpen);classList.replace()
const message =
document.querySelector(
'.message'
);
message.classList.replace(
'warning',
'success'
);Creating Elements
JavaScript can create completely new HTML elements at runtime. This is essential for displaying data, building lists, creating notifications, adding cards, and updating interfaces dynamically.
createElement()
const paragraph =
document.createElement(
'p'
);
console.log(paragraph);Creating an element does not automatically display it. The new element must be inserted into the document.
Adding Text to Elements
const paragraph =
document.createElement(
'p'
);
paragraph.textContent =
'Created with JavaScript';
console.log(paragraph);appendChild()
<div id="container"></div>const container =
document.getElementById(
'container'
);
const paragraph =
document.createElement(
'p'
);
paragraph.textContent =
'New Paragraph';
container.appendChild(
paragraph
);append()
The append() method can insert multiple nodes and text values at the end of an element.
const container =
document.querySelector(
'.container'
);
const title =
document.createElement(
'h2'
);
title.textContent =
'DOM Course';
const paragraph =
document.createElement(
'p'
);
paragraph.textContent =
'Learn JavaScript DOM.';
container.append(
title,
paragraph
);prepend()
The prepend() method inserts nodes or text at the beginning of an element.
const list =
document.querySelector(
'ul'
);
const item =
document.createElement(
'li'
);
item.textContent =
'First Item';
list.prepend(item);before()
The before() method inserts content immediately before an element.
const article =
document.querySelector(
'article'
);
const heading =
document.createElement(
'h2'
);
heading.textContent =
'Article Heading';
article.before(heading);after()
The after() method inserts content immediately after an element.
const article =
document.querySelector(
'article'
);
const note =
document.createElement(
'p'
);
note.textContent =
'End of Article';
article.after(note);insertAdjacentHTML()
The insertAdjacentHTML() method parses an HTML string and inserts it at a specified position relative to an element.
const container =
document.querySelector(
'.container'
);
container.insertAdjacentHTML(
'beforeend',
`
<div class="card">
<h3>New Card</h3>
<p>
Dynamic content.
</p>
</div>
`
);beforebegin
↓
<div class="container">
afterbegin
Existing Content
beforeend
</div>
↑
afterend- insertAdjacentHTML() parses strings as HTML.
- Do not insert untrusted user input directly.
- Use createElement() and textContent for safer dynamic content.
Removing Elements
DOM elements can be removed when they are no longer needed.
remove()
const message =
document.querySelector(
'.message'
);
message.remove();removeChild()
The removeChild() method removes a child node from its parent.
const list =
document.querySelector(
'ul'
);
const firstItem =
list.firstElementChild;
list.removeChild(
firstItem
);Replacing Elements
An existing DOM element can be replaced with another element.
replaceWith()
const oldHeading =
document.querySelector(
'h2'
);
const newHeading =
document.createElement(
'h2'
);
newHeading.textContent =
'Updated Heading';
oldHeading.replaceWith(
newHeading
);Cloning Elements
Existing DOM elements can be copied using cloneNode().
cloneNode()
const card =
document.querySelector(
'.card'
);
const copy =
card.cloneNode(true);
document.body.append(
copy
);- cloneNode(false) copies only the selected node.
- cloneNode(true) copies the node and its descendants.
- Cloning may duplicate id values.
- Update unique identifiers when necessary.
DOM Traversal
DOM traversal means moving through the relationships between elements. JavaScript can move from an element to its parent, children, or siblings.
<section class="course">
<h2>JavaScript</h2>
<p>Learn DOM</p>
<button>Start</button>
</section>section.course
│
├── h2
│
├── p
│
└── button
section is the PARENT
h2, p, button are CHILDREN
h2, p, button are SIBLINGSParent Elements
const button =
document.querySelector(
'button'
);
console.log(
button.parentElement
);
console.log(
button.parentNode
);parentElement returns the parent element, while parentNode returns the parent node, which may not always be an element.
Child Elements
const course =
document.querySelector(
'.course'
);
console.log(
course.children
);
console.log(
course.firstElementChild
);
console.log(
course.lastElementChild
);The children property returns child elements only. firstElementChild and lastElementChild return the first and last child elements.
Sibling Elements
const paragraph =
document.querySelector(
'.course p'
);
console.log(
paragraph.previousElementSibling
);
console.log(
paragraph.nextElementSibling
);closest()
The closest() method searches the selected element and then moves upward through its ancestors until it finds an element matching a CSS selector.
<article class="card">
<div class="content">
<button class="delete">
Delete
</button>
</div>
</article>const button =
document.querySelector(
'.delete'
);
const card =
button.closest(
'.card'
);
console.log(card);matches()
The matches() method checks whether an element matches a specified CSS selector.
const button =
document.querySelector(
'button'
);
console.log(
button.matches(
'.primary'
)
);Element Collections
Some DOM selection methods return collections rather than individual elements. Two common collection types are HTMLCollection and NodeList.
HTMLCollection
An HTMLCollection is an array-like collection of elements. Collections returned by methods such as getElementsByClassName() and getElementsByTagName() are live.
const items =
document.getElementsByClassName(
'item'
);
console.log(
items.length
);
console.log(
items[0]
);A live collection automatically reflects matching DOM changes.
NodeList
querySelectorAll() returns a static NodeList. The collection does not automatically add new matching elements created after the selection.
const items =
document.querySelectorAll(
'.item'
);
items.forEach(
function (item) {
console.log(
item.textContent
);
}
);HTMLCollection vs NodeList
HTMLCollection
Common Source:
getElementsByClassName()
getElementsByTagName()
Usually:
Live
Direct forEach():
No
Indexed Access:
Yes
NodeList
Common Source:
querySelectorAll()
Usually:
Static
Direct forEach():
Yes
Indexed Access:
YesLooping Through Elements
const cards =
document.querySelectorAll(
'.card'
);
cards.forEach(
function (card) {
console.log(
card.textContent
);
}
);const cards =
document.querySelectorAll(
'.card'
);
for (
const card
of cards
) {
console.log(
card.textContent
);
}Converting Collections to Arrays
const collection =
document.getElementsByClassName(
'item'
);
const items =
Array.from(
collection
);
console.log(
Array.isArray(items)
);const collection =
document.getElementsByClassName(
'item'
);
const items = [
...collection
];Working with Forms
The DOM allows JavaScript to read and update form controls such as text inputs, checkboxes, radio buttons, and select elements.
Reading Input Values
<input
id="username"
type="text"
value="Aarav"
>const username =
document.getElementById(
'username'
);
console.log(
username.value
);Changing Input Values
const username =
document.getElementById(
'username'
);
username.value =
'JavaScript Student';Checkboxes
<input
id="terms"
type="checkbox"
checked
>const terms =
document.getElementById(
'terms'
);
console.log(
terms.checked
);Radio Buttons
<label>
<input
type="radio"
name="level"
value="beginner"
checked
>
Beginner
</label>
<label>
<input
type="radio"
name="level"
value="advanced"
>
Advanced
</label>const selected =
document.querySelector(
'input[name="level"]:checked'
);
console.log(
selected.value
);Select Elements
<select id="language">
<option value="javascript">
JavaScript
</option>
<option value="java">
Java
</option>
<option value="python">
Python
</option>
</select>const language =
document.getElementById(
'language'
);
console.log(
language.value
);Form Elements Collection
<form id="profileForm">
<input
name="username"
value="Aarav"
>
<input
name="email"
value="aarav@example.com"
>
</form>const form =
document.getElementById(
'profileForm'
);
console.log(
form.elements.username.value
);
console.log(
form.elements.email.value
);Element Dimensions
The DOM provides properties for measuring element dimensions. Different properties include different parts of the CSS box model.
offsetWidth and offsetHeight
offsetWidth and offsetHeight include the content, padding, border, and scrollbar when present.
const box =
document.querySelector(
'.box'
);
console.log(
box.offsetWidth
);
console.log(
box.offsetHeight
);clientWidth and clientHeight
clientWidth and clientHeight include the content and padding but exclude borders.
console.log(
box.clientWidth
);
console.log(
box.clientHeight
);scrollWidth and scrollHeight
scrollWidth and scrollHeight represent the full size of the content, including content that is currently outside the visible area because of scrolling.
console.log(
box.scrollWidth
);
console.log(
box.scrollHeight
);offsetWidth / offsetHeight
Content
+ Padding
+ Border
+ Scrollbar
clientWidth / clientHeight
Content
+ Padding
scrollWidth / scrollHeight
Full Scrollable Content
+ PaddingElement Position
JavaScript can determine the size and position of an element relative to the browser viewport.
getBoundingClientRect()
const card =
document.querySelector(
'.card'
);
const rectangle =
card.getBoundingClientRect();
console.log(
rectangle.top
);
console.log(
rectangle.left
);
console.log(
rectangle.width
);
console.log(
rectangle.height
);The returned object also contains values such as right, bottom, x, and y.
Scrolling Elements
The DOM provides methods for moving elements into the visible viewport.
scrollIntoView()
const section =
document.getElementById(
'summary'
);
section.scrollIntoView({
behavior: 'smooth',
block: 'start'
});Document Ready State
JavaScript can only select elements that the browser has already parsed. Script placement and loading strategy therefore affect DOM access.
console.log(
document.readyState
);loading
The document is still loading.
interactive
HTML has been parsed.
complete
The document and resources
have finished loading.Script Loading
<script
src="script.js"
defer
></script>The defer attribute allows the script to download without blocking HTML parsing and executes it after the HTML has been parsed.
document.addEventListener(
'DOMContentLoaded',
function () {
const title =
document.getElementById(
'title'
);
console.log(title);
}
);- Use defer for traditional external scripts that need the DOM.
- Place scripts carefully when defer is not used.
- Make sure elements exist before selecting them.
- Handle null when an element may not exist.
Complete DOM Example
The following example creates a dynamic task manager. Users can add tasks, mark tasks as completed, delete tasks, filter tasks, and view live statistics. The example focuses on DOM selection, creation, content updates, classes, attributes, traversal, and removal.
<div class="task-app">
<header class="task-header">
<p class="eyebrow">
JavaScript DOM Project
</p>
<h2>
Task Manager
</h2>
<p>
Create and manage tasks dynamically.
</p>
</header>
<div class="task-form">
<input
id="taskInput"
type="text"
placeholder="Enter a new task"
>
<select id="priorityInput">
<option value="low">
Low Priority
</option>
<option value="medium">
Medium Priority
</option>
<option value="high">
High Priority
</option>
</select>
<button id="addTaskButton">
Add Task
</button>
</div>
<div class="task-filters">
<button
class="filter-button active"
data-filter="all"
>
All
</button>
<button
class="filter-button"
data-filter="pending"
>
Pending
</button>
<button
class="filter-button"
data-filter="completed"
>
Completed
</button>
</div>
<div
id="message"
class="task-message"
>
Add your first task.
</div>
<ul id="taskList"></ul>
<div class="task-stats">
<div>
<span>Total</span>
<strong id="totalCount">
0
</strong>
</div>
<div>
<span>Pending</span>
<strong id="pendingCount">
0
</strong>
</div>
<div>
<span>Completed</span>
<strong id="completedCount">
0
</strong>
</div>
</div>
</div>.task-app {
max-width: 760px;
margin: 40px auto;
padding: 28px;
border-radius: 18px;
background: var(--bg-secondary);
}
.task-header {
margin-bottom: 24px;
}
.eyebrow {
margin-bottom: 8px;
color: var(--accent-light);
font-size: 0.8rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
}
.task-form {
display: grid;
grid-template-columns: 1fr auto auto;
gap: 10px;
margin-bottom: 18px;
}
.task-form input,
.task-form select,
.task-form button {
padding: 12px 14px;
border-radius: 10px;
}
.task-filters {
display: flex;
gap: 8px;
margin-bottom: 18px;
}
.filter-button {
padding: 8px 14px;
border: none;
border-radius: 50px;
cursor: pointer;
}
.filter-button.active {
background: var(--accent);
color: white;
}
.task-message {
margin-bottom: 14px;
color: var(--text-secondary);
}
#taskList {
display: flex;
flex-direction: column;
gap: 10px;
padding: 0;
list-style: none;
}
.task-item {
display: flex;
align-items: center;
gap: 12px;
padding: 14px;
border: 1px solid var(--border-color);
border-radius: 12px;
}
.task-content {
flex: 1;
}
.task-title {
margin: 0 0 4px;
}
.task-priority {
font-size: 0.75rem;
color: var(--text-secondary);
}
.task-item.completed .task-title {
text-decoration: line-through;
opacity: 0.6;
}
.task-actions {
display: flex;
gap: 8px;
}
.task-actions button {
padding: 7px 10px;
border: none;
border-radius: 8px;
cursor: pointer;
}
.task-stats {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
margin-top: 20px;
}
.task-stats div {
padding: 14px;
border-radius: 12px;
background: var(--bg-primary);
}
.task-stats span,
.task-stats strong {
display: block;
}
.task-stats span {
margin-bottom: 6px;
font-size: 0.8rem;
color: var(--text-secondary);
}const taskInput =
document.getElementById(
'taskInput'
);
const priorityInput =
document.getElementById(
'priorityInput'
);
const addTaskButton =
document.getElementById(
'addTaskButton'
);
const taskList =
document.getElementById(
'taskList'
);
const message =
document.getElementById(
'message'
);
const totalCount =
document.getElementById(
'totalCount'
);
const pendingCount =
document.getElementById(
'pendingCount'
);
const completedCount =
document.getElementById(
'completedCount'
);
const filterButtons =
document.querySelectorAll(
'.filter-button'
);
let currentFilter = 'all';
addTaskButton.addEventListener(
'click',
addTask
);
taskInput.addEventListener(
'keydown',
function (event) {
if (
event.key === 'Enter'
) {
addTask();
}
}
);
filterButtons.forEach(
function (button) {
button.addEventListener(
'click',
function () {
currentFilter =
button.dataset.filter;
updateActiveFilter(
button
);
filterTasks();
}
);
}
);
function addTask() {
const title =
taskInput.value.trim();
const priority =
priorityInput.value;
if (title === '') {
showMessage(
'Enter a task before adding it.'
);
taskInput.focus();
return;
}
const taskItem =
createTaskElement(
title,
priority
);
taskList.append(
taskItem
);
taskInput.value = '';
taskInput.focus();
showMessage(
'Task added successfully.'
);
updateStatistics();
filterTasks();
}
function createTaskElement(
title,
priority
) {
const taskItem =
document.createElement(
'li'
);
taskItem.classList.add(
'task-item'
);
taskItem.dataset.status =
'pending';
const content =
document.createElement(
'div'
);
content.classList.add(
'task-content'
);
const taskTitle =
document.createElement(
'h3'
);
taskTitle.classList.add(
'task-title'
);
taskTitle.textContent =
title;
const priorityText =
document.createElement(
'span'
);
priorityText.classList.add(
'task-priority'
);
priorityText.textContent =
`${priority} priority`;
content.append(
taskTitle,
priorityText
);
const actions =
document.createElement(
'div'
);
actions.classList.add(
'task-actions'
);
const completeButton =
document.createElement(
'button'
);
completeButton.type =
'button';
completeButton.textContent =
'Complete';
completeButton.classList.add(
'complete-button'
);
const deleteButton =
document.createElement(
'button'
);
deleteButton.type =
'button';
deleteButton.textContent =
'Delete';
deleteButton.classList.add(
'delete-button'
);
completeButton.addEventListener(
'click',
function () {
toggleTask(
taskItem,
completeButton
);
}
);
deleteButton.addEventListener(
'click',
function () {
taskItem.remove();
showMessage(
'Task deleted.'
);
updateStatistics();
filterTasks();
}
);
actions.append(
completeButton,
deleteButton
);
taskItem.append(
content,
actions
);
return taskItem;
}
function toggleTask(
taskItem,
button
) {
const isCompleted =
taskItem.classList.toggle(
'completed'
);
if (isCompleted) {
taskItem.dataset.status =
'completed';
button.textContent =
'Undo';
showMessage(
'Task completed.'
);
} else {
taskItem.dataset.status =
'pending';
button.textContent =
'Complete';
showMessage(
'Task moved back to pending.'
);
}
updateStatistics();
filterTasks();
}
function updateActiveFilter(
activeButton
) {
filterButtons.forEach(
function (button) {
button.classList.remove(
'active'
);
}
);
activeButton.classList.add(
'active'
);
}
function filterTasks() {
const tasks =
taskList.querySelectorAll(
'.task-item'
);
tasks.forEach(
function (task) {
const status =
task.dataset.status;
const shouldShow =
currentFilter === 'all'
||
currentFilter === status;
task.hidden =
!shouldShow;
}
);
}
function updateStatistics() {
const tasks =
taskList.querySelectorAll(
'.task-item'
);
const completedTasks =
taskList.querySelectorAll(
'.task-item.completed'
);
const total =
tasks.length;
const completed =
completedTasks.length;
const pending =
total - completed;
totalCount.textContent =
total;
pendingCount.textContent =
pending;
completedCount.textContent =
completed;
}
function showMessage(text) {
message.textContent =
text;
}- Selecting elements by ID.
- Selecting multiple elements with querySelectorAll().
- Reading input values.
- Removing extra whitespace with trim().
- Validating empty input.
- Creating elements with createElement().
- Adding plain text with textContent.
- Adding CSS classes with classList.add().
- Toggling CSS classes with classList.toggle().
- Removing CSS classes with classList.remove().
- Using custom data attributes.
- Reading data attributes with dataset.
- Appending multiple elements.
- Removing elements with remove().
- Selecting descendants from a specific element.
- Updating text dynamically.
- Using the hidden property.
- Updating live statistics.
- Filtering DOM elements.
- Creating reusable functions.
- Combining DOM manipulation with events.
- Building a complete dynamic interface.
DOM Processing Flow
HTML DOCUMENT
│
▼
┌──────────────────────────────┐
│ BROWSER PARSES HTML │
│ │
│ Creates DOM Tree │
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ SELECT │
│ │
│ getElementById() │
│ querySelector() │
│ querySelectorAll() │
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ READ │
│ │
│ textContent │
│ value │
│ attributes │
│ dataset │
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ PROCESS │
│ │
│ Conditions │
│ Functions │
│ Arrays │
│ Objects │
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ MODIFY │
│ │
│ Content │
│ Attributes │
│ Classes │
│ Styles │
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ CREATE OR REMOVE │
│ │
│ createElement() │
│ append() │
│ remove() │
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ BROWSER UPDATES PAGE │
│ │
│ User sees new interface │
└──────────────────────────────┘Real-World Applications
Form Validation
Read inputs and display validation messages dynamically.
Shopping Carts
Create, update, and remove cart items.
Task Managers
Add, complete, filter, and delete tasks.
Notifications
Create alerts, toast messages, and status indicators.
Dashboards
Update statistics, cards, tables, and charts.
Search Interfaces
Filter visible elements based on user input.
Theme Switchers
Toggle classes to change light and dark themes.
Navigation Menus
Open and close responsive menus.
Modals
Show and hide dialogs and overlays.
Accordions
Expand and collapse content sections.
Tabs
Switch visible content based on selected tabs.
Dynamic Content
Convert JavaScript and API data into HTML elements.
Common Beginner Mistakes
- Confusing the DOM with HTML source code.
- Assuming DOM changes automatically modify the original HTML file.
- Trying to select elements before the browser has parsed them.
- Forgetting to use defer when appropriate.
- Using the wrong element ID.
- Including # inside getElementById().
- Forgetting # when selecting an ID with querySelector().
- Forgetting . when selecting a class with querySelector().
- Expecting getElementById() to return multiple elements.
- Expecting querySelector() to return all matching elements.
- Forgetting that querySelector() returns only the first match.
- Forgetting that querySelectorAll() returns a collection.
- Trying to use textContent directly on a NodeList.
- Forgetting to loop through multiple selected elements.
- Assuming every selector always finds an element.
- Ignoring the possibility of null.
- Trying to access a property of null.
- Using innerHTML when only plain text is required.
- Inserting untrusted user input with innerHTML.
- Inserting untrusted content with insertAdjacentHTML().
- Confusing textContent and innerHTML.
- Expecting HTML tags inside textContent to render as HTML.
- Expecting innerText and textContent to always return identical values.
- Using className when only one class should change.
- Accidentally replacing all classes with className.
- Forgetting that classList.add() requires class names without dots.
- Writing classList.add(".active") instead of classList.add("active").
- Writing classList.remove(".active") with a dot.
- Forgetting that toggle() can both add and remove a class.
- Changing many styles directly instead of using CSS classes.
- Using CSS hyphenated property names directly with dot notation.
- Writing element.style.background-color.
- Expecting element.style to return every applied CSS rule.
- Forgetting to use getComputedStyle() for final computed styles.
- Using Math or string operations on input values without conversion.
- Forgetting that input.value returns a string.
- Reading checkbox value when checked state is required.
- Using value instead of checked for checkboxes.
- Forgetting :checked when selecting the selected radio button.
- Creating an element but forgetting to insert it into the document.
- Calling createElement() and expecting immediate browser output.
- Appending an element to the wrong parent.
- Confusing append() and appendChild().
- Forgetting that appendChild() accepts one node.
- Removing an element before confirming that it exists.
- Using removeChild() with an element that is not a child of the selected parent.
- Cloning elements without considering duplicate IDs.
- Using cloneNode(false) when child content is also required.
- Confusing childNodes with children.
- Confusing firstChild with firstElementChild.
- Forgetting that whitespace can create text nodes.
- Using parentNode when specifically expecting an element.
- Traversing too many levels with repeated parentElement calls.
- Ignoring closest() for ancestor searches.
- Assuming closest() always returns an element.
- Forgetting that closest() can return null.
- Confusing HTMLCollection and NodeList.
- Assuming every DOM collection supports forEach().
- Assuming every DOM collection is a real array.
- Trying to use array methods directly on an HTMLCollection.
- Forgetting that some HTMLCollections are live.
- Modifying a live collection while looping through it without understanding the effect.
- Assuming querySelectorAll() automatically updates after new elements are added.
- Reading dimensions before an element is rendered.
- Confusing offsetWidth, clientWidth, and scrollWidth.
- Assuming getBoundingClientRect() returns document coordinates.
- Forgetting that its position is relative to the viewport.
- Using repeated DOM queries unnecessarily.
- Selecting the same static element many times.
- Creating excessive DOM updates inside large loops.
- Mixing data processing and DOM manipulation everywhere.
- Using unclear variable names such as x or el for important elements.
- Creating duplicate IDs dynamically.
- Forgetting accessibility when dynamically creating buttons or controls.
- Using clickable div elements when a button is appropriate.
- Changing only visual state without updating meaningful element state.
- Failing to test the page when expected elements are missing.
// ❌ Wrong
document.getElementById(
'#title'
);
// ✅ Correct
document.getElementById(
'title'
);
// ❌ Wrong
document.querySelector(
'title'
);
// ✅ Select ID
document.querySelector(
'#title'
);
// ❌ Wrong
const items =
document.querySelectorAll(
'.item'
);
// items.textContent = 'Updated';
// ✅ Correct
items.forEach(
function (item) {
item.textContent =
'Updated';
}
);
// ❌ Wrong class name
element.classList.add(
'.active'
);
// ✅ Correct
element.classList.add(
'active'
);
// ❌ HTML input value is a string
const total =
firstInput.value
+
secondInput.value;
// ✅ Convert first
const total =
Number(firstInput.value)
+
Number(secondInput.value);
// ❌ Element may not exist
// document.querySelector(
// '.unknown'
// ).textContent = 'Hello';
// ✅ Check first
const element =
document.querySelector(
'.unknown'
);
if (element) {
element.textContent =
'Hello';
}Best Practices
- Understand the DOM as a browser-created object representation of the document.
- Use descriptive variable names for selected elements.
- Use const for element references that are not reassigned.
- Use getElementById() for direct unique ID selection when appropriate.
- Use querySelector() for flexible single-element selection.
- Use querySelectorAll() for flexible multiple-element selection.
- Use valid CSS selectors with querySelector methods.
- Remember that querySelector() returns only the first match.
- Remember that querySelectorAll() returns a NodeList.
- Check whether optional elements exist before using them.
- Handle null when a selector may not find a match.
- Cache frequently used static element references.
- Avoid repeating identical DOM queries unnecessarily.
- Use textContent for plain text.
- Use innerHTML only when HTML parsing is actually required.
- Never insert untrusted user input directly with innerHTML.
- Never insert untrusted user input directly with insertAdjacentHTML().
- Prefer createElement() and textContent for dynamic user-controlled content.
- Use getAttribute() when the exact attribute value is needed.
- Use setAttribute() for general attribute updates.
- Use direct properties for common states such as value, checked, and disabled.
- Use data attributes for element-specific custom information.
- Use dataset for convenient access to data attributes.
- Use camelCase when accessing hyphenated data attributes through dataset.
- Use the style property for truly dynamic inline values.
- Prefer CSS classes for reusable visual states.
- Use classList instead of replacing the entire className when changing individual classes.
- Use classList.add() to add classes.
- Use classList.remove() to remove classes.
- Use classList.toggle() for two-state interfaces.
- Use classList.contains() when state checking is required.
- Use getComputedStyle() when reading final applied styles.
- Use createElement() to create structured elements.
- Set text with textContent.
- Set necessary properties and attributes before insertion.
- Use append() when inserting multiple nodes.
- Use prepend() when inserting content at the beginning.
- Use before() and after() for sibling insertion.
- Use remove() for straightforward element removal.
- Use cloneNode(true) only when descendant content should also be copied.
- Avoid duplicate IDs when cloning elements.
- Use children when you need element children only.
- Use firstElementChild and lastElementChild to avoid text-node confusion.
- Use previousElementSibling and nextElementSibling for element traversal.
- Use closest() for ancestor searches.
- Check the result of closest() when a matching ancestor may not exist.
- Understand whether a collection is live or static.
- Use forEach() with NodeLists returned by querySelectorAll().
- Use for...of when it improves clarity.
- Convert collections to arrays when array methods are required.
- Remember that HTML input values are strings.
- Convert input values before numeric calculations.
- Use checked for checkbox and radio state.
- Use value for text inputs and select elements.
- Use meaningful HTML elements when creating interactive controls.
- Preserve accessibility when modifying the DOM.
- Avoid excessive DOM updates inside large loops.
- Create elements in memory before inserting them when practical.
- Separate data logic from rendering logic.
- Create reusable rendering functions.
- Create reusable element factory functions when many similar elements are needed.
- Use data attributes to connect elements with application data when appropriate.
- Use defer for external scripts that depend on parsed HTML.
- Test DOM code when elements exist.
- Test DOM code when optional elements are missing.
- Test empty collections.
- Test dynamically added elements.
- Test dynamically removed elements.
- Test keyboard accessibility.
- Test different screen sizes.
- Keep DOM manipulation clear and predictable.
Frequently Asked Questions
What does DOM stand for?
DOM stands for Document Object Model.
What is the DOM?
The DOM is a browser-created object representation of an HTML document.
Is the DOM the same as HTML?
No. HTML is source markup, while the DOM is the object structure created from the document.
Who creates the DOM?
The browser creates the DOM when it parses the HTML document.
Why does JavaScript need the DOM?
The DOM gives JavaScript a standard way to access and modify the web page.
What is a DOM tree?
It is the hierarchical structure of nodes representing the document.
What is a DOM node?
A node is an item in the DOM tree, such as a document, element, text, or comment node.
What is the document object?
It is the main JavaScript object representing the loaded HTML document.
How do I select an element by ID?
Use document.getElementById() or a CSS ID selector with querySelector().
Should I include # in getElementById()?
No. Pass only the ID value.
Should I include # in querySelector() for an ID?
Yes, because querySelector() uses CSS selector syntax.
How do I select elements by class?
Use getElementsByClassName() or querySelectorAll() with a class selector.
What does querySelector() return?
The first matching element or null.
What does querySelectorAll() return?
A static NodeList containing all matching elements.
What happens when querySelector() finds nothing?
It returns null.
Can querySelector() use CSS selectors?
Yes. It accepts valid CSS selectors.
How do I change text?
Select the element and assign a new value to textContent or innerText.
What is the difference between textContent and innerHTML?
textContent handles plain text, while innerHTML reads or parses HTML markup.
What is the difference between textContent and innerText?
textContent represents textual content including hidden descendants, while innerText focuses on rendered visible text.
Is innerHTML safe?
It can be safe with trusted content, but inserting untrusted input directly can create security vulnerabilities.
How do I read an attribute?
Use getAttribute() or an appropriate element property.
How do I change an attribute?
Use setAttribute() or an appropriate element property.
How do I remove an attribute?
Use removeAttribute().
How do I check whether an attribute exists?
Use hasAttribute().
What are data attributes?
They are custom HTML attributes beginning with data- that store additional element information.
How do I access data attributes?
Use the dataset property.
How does data-user-id appear in dataset?
It becomes dataset.userId.
How do I change an inline style?
Use the element style property.
How do I write background-color in JavaScript style syntax?
Use backgroundColor.
How do I read the final applied CSS style?
Use getComputedStyle().
How do I add a CSS class?
Use classList.add().
How do I remove a CSS class?
Use classList.remove().
How do I toggle a CSS class?
Use classList.toggle().
How do I check whether an element has a class?
Use classList.contains().
How do I replace one class with another?
Use classList.replace().
Should class names passed to classList include a dot?
No. Pass the class name without the CSS selector dot.
How do I create an HTML element?
Use document.createElement().
Does createElement() automatically display the element?
No. The element must be inserted into the document.
How do I add an element to the end of a parent?
Use append(), appendChild(), or another insertion method.
What is the difference between append() and appendChild()?
append() can accept multiple nodes and strings, while appendChild() accepts one node.
How do I add content at the beginning of an element?
Use prepend().
How do I insert content before an element?
Use before().
How do I insert content after an element?
Use after().
How do I remove an element?
Use remove().
How do I replace an element?
Use replaceWith().
How do I copy an element?
Use cloneNode().
What does cloneNode(true) do?
It creates a deep clone including descendant nodes.
What does cloneNode(false) do?
It copies only the selected node without descendants.
What is DOM traversal?
DOM traversal means navigating between related nodes or elements.
How do I access a parent element?
Use parentElement.
How do I access child elements?
Use children.
How do I access the first child element?
Use firstElementChild.
How do I access the last child element?
Use lastElementChild.
How do I access the next sibling element?
Use nextElementSibling.
How do I access the previous sibling element?
Use previousElementSibling.
What does closest() do?
It searches the element and its ancestors for the nearest element matching a CSS selector.
What does matches() do?
It checks whether an element matches a CSS selector.
What is an HTMLCollection?
It is an array-like collection of elements, often live.
What is a NodeList?
It is an array-like collection of nodes. querySelectorAll() returns a static NodeList.
Is an HTMLCollection an array?
No.
Is a NodeList an array?
No.
How do I convert a DOM collection into an array?
Use Array.from() or the spread operator when supported by the collection.
Are HTML input values numbers?
No. The value property returns a string.
How do I read a checkbox state?
Use the checked property.
How do I read a selected radio button?
Select the checked radio input and read its value.
How do I read a select value?
Use the value property of the select element.
What does offsetWidth include?
It includes content, padding, border, and scrollbar when present.
What does clientWidth include?
It includes content and padding but excludes borders.
What does scrollWidth represent?
It represents the full width of scrollable content.
How do I find an element position?
Use getBoundingClientRect().
What is getBoundingClientRect() relative to?
Its position values are relative to the viewport.
How do I smoothly scroll to an element?
Use scrollIntoView() with behavior set to smooth.
Why does my selector return null?
The selector may be incorrect, the element may not exist, or the script may run before the element is parsed.
What does the defer attribute do?
It allows an external script to download without blocking HTML parsing and executes it after parsing is complete.
Does changing the DOM change the original HTML file?
No. It changes the current in-memory document displayed by the browser.
Key Takeaways
- DOM stands for Document Object Model.
- The browser creates the DOM from the HTML document.
- The DOM represents the document as a tree of objects.
- Everything in the DOM is represented through nodes.
- The document object is the main entry point to the DOM.
- getElementById() selects an element by ID.
- getElementsByClassName() returns a live HTMLCollection.
- getElementsByTagName() returns a live HTMLCollection.
- querySelector() returns the first CSS selector match.
- querySelectorAll() returns a static NodeList.
- Selectors can return null when no element matches.
- textContent reads and writes plain text.
- innerText focuses on rendered visible text.
- innerHTML reads and writes HTML markup.
- Untrusted input should not be inserted directly with innerHTML.
- getAttribute() reads attributes.
- setAttribute() creates or updates attributes.
- hasAttribute() checks attribute existence.
- removeAttribute() removes attributes.
- dataset provides access to data attributes.
- The style property changes inline styles.
- getComputedStyle() reads final calculated styles.
- classList manages individual CSS classes.
- classList.add() adds classes.
- classList.remove() removes classes.
- classList.toggle() switches class state.
- classList.contains() checks class existence.
- classList.replace() replaces a class.
- createElement() creates new elements.
- Created elements must be inserted into the document.
- appendChild() adds one child node.
- append() can add multiple nodes and strings.
- prepend() inserts content at the beginning.
- before() and after() insert siblings.
- remove() deletes an element.
- replaceWith() replaces an element.
- cloneNode() copies an element.
- DOM traversal moves through element relationships.
- parentElement accesses an element parent.
- children accesses child elements.
- Sibling properties move between related elements.
- closest() finds a matching ancestor.
- matches() checks a CSS selector match.
- HTMLCollection and NodeList are array-like but are not arrays.
- Some DOM collections are live while others are static.
- Input values are strings.
- Checkbox and radio state is read with checked.
- Element dimensions can be measured through DOM properties.
- getBoundingClientRect() returns size and viewport position.
- scrollIntoView() can move an element into the viewport.
- Scripts must run after required elements are available.
- The defer attribute is useful for DOM-dependent external scripts.
- DOM manipulation is the foundation of interactive web interfaces.
Summary
The Document Object Model is the connection between JavaScript and the visible HTML document. The browser converts HTML into a structured tree of objects that JavaScript can access and modify.
The document object provides methods such as getElementById(), querySelector(), and querySelectorAll() for finding elements.
Properties such as textContent, innerText, and innerHTML allow JavaScript to read and change element content. Each property serves a different purpose, and plain text should normally use textContent.
Attributes can be managed using getAttribute(), setAttribute(), hasAttribute(), and removeAttribute(). Custom data attributes can be accessed conveniently through dataset.
The style property allows inline style changes, while classList provides a cleaner approach for reusable visual states through CSS classes.
JavaScript can create new elements with createElement(), add content, insert elements using append(), prepend(), before(), and after(), and remove elements when they are no longer required.
DOM traversal allows JavaScript to move through parent, child, sibling, and ancestor relationships. Methods such as closest() make it easier to find related elements.
DOM collections such as HTMLCollection and NodeList represent groups of elements. Understanding whether a collection is live or static is important when the document changes dynamically.
Forms, element dimensions, positions, scrolling, and document loading can all be controlled through DOM APIs.
Mastering the DOM allows you to build dynamic forms, task managers, shopping carts, menus, tabs, modals, notifications, dashboards, filters, theme switchers, and other interactive web interfaces.
- You understand what the DOM is.
- You understand why JavaScript needs the DOM.
- You understand how HTML becomes a DOM tree.
- You understand DOM nodes.
- You know the main node types.
- You understand the document object.
- You can select elements by ID.
- You can select elements by class.
- You can select elements by tag name.
- You can use querySelector().
- You can use querySelectorAll().
- You can use CSS selectors in JavaScript.
- You can read and change text content.
- You understand textContent.
- You understand innerText.
- You understand innerHTML.
- You can read attributes.
- You can create and update attributes.
- You can check attributes.
- You can remove attributes.
- You can work with data attributes.
- You can use dataset.
- You can change inline styles.
- You can read computed styles.
- You can manage CSS classes.
- You can add classes.
- You can remove classes.
- You can toggle classes.
- You can check classes.
- You can replace classes.
- You can create new elements.
- You can add text to elements.
- You can append elements.
- You can prepend elements.
- You can insert siblings.
- You can remove elements.
- You can replace elements.
- You can clone elements.
- You can traverse the DOM.
- You can access parents.
- You can access children.
- You can access siblings.
- You can use closest().
- You can use matches().
- You understand HTMLCollection.
- You understand NodeList.
- You can loop through selected elements.
- You can convert collections into arrays.
- You can read form values.
- You can work with checkboxes.
- You can work with radio buttons.
- You can work with select elements.
- You can measure element dimensions.
- You can find element positions.
- You can scroll elements into view.
- You understand document loading.
- You can build a complete dynamic DOM application.
- You are ready to learn JavaScript Events.