JavaScript course menu
Introduction to the DOM: How JavaScript Sees and Changes Web Pages
Understand the Document Object Model (DOM): how the browser turns HTML into a tree of nodes, the document and window objects, elements versus nodes, where to put scripts so elements exist, and a first interactive example.
On this page
When a browser loads a page, it reads the HTML and builds the DOM (Document Object Model): a tree of objects, one for each element, piece of text and comment. JavaScript cannot change the HTML file, but it can read and change the DOM, and the browser immediately updates what you see.
HTML becomes a tree#
<body>
<h1>Shopping list</h1>
<ul id="list">
<li>Milk</li>
<li>Bread</li>
</ul>
</body>becomes:
body
├── h1
│ └── "Shopping list"
└── ul#list
├── li
│ └── "Milk"
└── li
└── "Bread"Every box in this tree is a node. Elements (<h1>, <ul>, <li>) are element nodes; the text inside them is stored in text nodes. Most of the time you work with elements.
document and window#
Two global objects are your entry points:
document itself is a property of window, and you can write either window.document or just document.
A first DOM program#
<h1 id="title">Hello!</h1>
<p>Click the button to change the heading.</p>
<button id="change">Change heading</button>const title = document.querySelector("#title");
const button = document.querySelector("#change");
button.addEventListener("click", () => {
title.textContent = "You changed the DOM!";
title.style.color = "crimson";
});The pattern you will use again and again:
- Select an element:
document.querySelector("#title"). - Listen for an event:
button.addEventListener("click", ...). - Change the DOM in response:
title.textContent = ....
The following lessons cover each step: Selecting Elements, Changing Content, Attributes and Classes, Creating and Removing Elements and Events.
Scripts must run after the elements exist#
If a script runs before the browser has read the elements it looks for, querySelector returns null:
<head>
<script>
// Runs immediately, before the body exists
console.log(document.querySelector("h1")); // null
</script>
</head>
<body>
<h1>Title</h1>
</body>Fixes, in order of preference:
- Load scripts with
defer(or astype="module"), which run after the document has been parsed:<script src="app.js" defer></script>. - Put the
<script>at the end of<body>. - Wait for the
DOMContentLoadedevent:document.addEventListener("DOMContentLoaded", start);.
(The Result frames on this site put the script at the end of the body, which is why the examples work.)
Exploring the DOM yourself#
Open the developer tools on any page (F12):
- The Elements panel shows the live DOM. Select an element there, then type
$0in the Console to get that element in JavaScript. - In the Console, try
document.title,document.querySelectorAll("a").lengthordocument.body.style.background = "lavender".
Changes you make are temporary and disappear when you reload.
The DOM is not the HTML file#
- The DOM includes fixes the browser made to invalid HTML.
- It changes as JavaScript runs; View Page Source shows the original file, while the Elements panel shows the current DOM.
- Frameworks such as React also update the DOM, but they do it for you based on your data.
Practice#
Practice exercise
Make a page with a paragraph <p id="greeting">Good morning</p> and two buttons, "Morning" and "Evening", that change the paragraph's text to "Good morning" and "Good evening".
Show solution
<p id="greeting">Good morning</p>
<button id="morning">Morning</button>
<button id="evening">Evening</button>const greeting = document.querySelector("#greeting");
document.querySelector("#morning").addEventListener("click", () => {
greeting.textContent = "Good morning";
});
document.querySelector("#evening").addEventListener("click", () => {
greeting.textContent = "Good evening";
});Key takeaway#
Finished this lesson?