The DOM: select, create & modify
Find elements, change text, classes and attributes, create and remove nodes, and handle a first click.
The DOM (Document Object Model) is the browser's live, in-memory tree of your HTML page. Every tag becomes an element node that JavaScript can read and change — and when you change the tree, the page updates. That's how every interactive website works, and it's what frameworks like React do for you under the hood.
The document is a tree#
document is the root. <html> contains <body>, which contains <header>, <ul> and so on. Elements have parents, children and siblings, just like a family tree.
Try it: open DevTools, pick the Elements tab, click an element, then type
$0in the Console — it refers to the selected element.
Selecting elements#
querySelector(css)returns the first match ornullif nothing matches.querySelectorAll(css)returns a staticNodeList. It hasforEach; convert with[...list]orArray.from(list)to usemapandfilter.- You can search inside any element:
list.querySelector("li").
Any CSS selector works: "nav a.active", "[data-id='3']", "input[type=email]", "li:last-child".
Moving around the tree
closest is especially useful with events, as you'll see in the next lesson.
Changing content#
Use
textContentfor text.innerHTMLparses its string as HTML, so never put user input into it — a "name" like<img src=x onerror="stealCookies()">would run code. That attack is called cross-site scripting (XSS).
Classes, styles and attributes#
Prefer toggling classes and keeping the styles in CSS — it's easier to maintain than setting many inline styles.
Data attributes
Store small bits of data on elements with data-* attributes:
Form element properties
Many attributes are also properties:
Creating, inserting and removing elements#
append accepts several nodes and strings: list.append(item1, item2, "text").
Building many elements efficiently
Every insert can make the browser recalculate layout. When adding lots of items, build them first and insert once:
Templates for bigger chunks
For complex markup, use an HTML <template> and clone it:
This keeps HTML in HTML and is safe, because you fill in values with textContent.
Your first event#
Pages become interactive when you listen for events:
addEventListener(type, handler) registers a function to run each time the event happens. Common types: click, input, change, submit, keydown, pointerenter, scroll. The next lesson dives into events properly.
A tiny complete example#
Save this as a single HTML file and open it:
Type in the box and the paragraph updates live — and because it uses textContent, typing <b>hi</b> shows the tags as text rather than running HTML.
Common mistakes#
Cannot read properties of null— your selector matched nothing, or the script ran before the element existed. Check the selector and usedeferortype="module".- Calling
querySelectorAll(...).map— NodeLists don't havemap; spread them into an array first. - Using
innerHTML +=in a loop — it re-parses everything each time, destroys event listeners and risks XSS. - Forgetting that
datasetandinput.valueare always strings.
What's next#
You can find and change anything on the page. Next, master events: the event object, bubbling, delegation and keyboard handling.
Check your understanding
Quick quiz
1.Which method returns the first element matching a CSS selector?
2.Why prefer
textContentoverinnerHTMLfor user-provided text?3.How do you read the value of
<div data-lesson-id="42">in JavaScript?
Finished reading?
Mark this lesson complete to track your progress.