RizTech Academy logo
RizTech Academy
The DOMLesson 1 of 720 min

What the DOM actually is

Six modules of JavaScript with no web page in sight. That changes now. The DOM is the bridge between the language you have been learning and the thing a person actually looks at.

What it actually is

You write HTML. The browser reads it and builds a tree of objects in memory, one per element. That tree is the Document Object Model.

<ul id="orders">
  <li class="order">Priya</li>
  <li class="order">Arjun</li>
</ul>

becomes, roughly:

ul#orders
├── li.order  ("Priya")
└── li.order  ("Arjun")

Every node in that tree is a JavaScript object with properties and methods. document is the entry point, and from there you can read anything, change anything, add and remove.

Three things follow from this, and each surprises somebody.

The DOM is not your HTML file. It is built from it and then lives its own life. Change the page with JavaScript and the tree changes; the file on disk does not. Reload and everything you did is gone — which is why module 4's JSON and this module's localStorage lesson matter.

View Source and Inspect show different things. View Source is the HTML the server sent. The Elements panel shows the current tree, including everything your script has done since. When they disagree, you are looking at the difference between what arrived and what is there now.

The DOM is not part of JavaScript. It is a browser feature that JavaScript is given access to, which is exactly why document is not defined in Node — module 1's lesson, now with its proper explanation. The same split applies to fetch, localStorage and alert.

Getting hold of a node

<h1 id="heading">Loading…</h1>
<script src="app.js" defer></script>
const heading = document.getElementById('heading');

console.log(heading.textContent);
heading.textContent = 'Tiffin orders';
Loading…

The page now reads Tiffin orders. One assignment, and the browser re-rendered.

That is the whole shape of DOM work: find a node, read or change it. The next lesson is all of finding; the rest of the module is changing and reacting.

The node is a live reference

const heading = document.getElementById('heading');
heading.textContent = 'One';
heading.textContent = 'Two';

heading is not a copy of the element. It is a reference to the object in the tree — module 4's reference semantics, now with visible consequences. Both assignments hit the same element, and the page shows Two.

Keep a reference once rather than looking it up repeatedly. Searching the tree costs real work, and doing it inside a loop is the commonest reason a page feels slow on a mid-range phone.

Parents, children, siblings

Every node knows its neighbours:

Property Gives
parentElement The element containing it
children Its child elements
firstElementChild / lastElementChild First and last child element
nextElementSibling / previousElementSibling The element before or after
closest(selector) The nearest ancestor matching — including itself

Note the word "Element" in all of them. There is an older set — childNodes, firstChild, nextSibling — that counts nodes rather than elements, and whitespace between tags is a text node. So firstChild on a prettily indented list is usually a newline, not the first li. Use the Element versions.

closest is the one you will use most, and event delegation is built on it.

The cost of touching it

Honest, because it shapes how you write everything later.

Reading and writing the DOM is much slower than working with plain JavaScript. Each change can make the browser recalculate layout, and doing that a hundred times in a loop is a hundred recalculations.

for (const order of orders) {
  list.innerHTML += `<li>${order.customer}</li>`;
}

That is the slow way twice over: it re-parses the entire list on every pass, and it throws away and rebuilds every existing node — so anything the user had typed or selected inside is destroyed.

Build in memory, touch the DOM once:

const html = orders.map((order) => `<li>${order.customer}</li>`).join('');
list.innerHTML = html;

One write. map and join from module 4 doing exactly the job they are for.

This is also the entire argument for React and its relatives. They let you describe what the page should look like and work out the minimum set of changes themselves. You are doing it by hand for two modules so that when a framework does it for you, you know what it is doing.

Check your work

The DOM is a tree of objects the browser builds from your HTML, not the HTML file itself. Changing it does not change the file, and a reload discards your changes.

View Source shows what the server sent; the Elements panel shows the current tree. A difference between them is your JavaScript's work.

The DOM is a browser feature, not part of JavaScript — which is why Node has no document.

document.getElementById('heading').textContent = 'x' updates the page immediately. The element object is a live reference, so repeated assignments all hit the same node and the last one wins.

Use the Element navigation properties. firstChild on indented HTML is usually a whitespace text node; firstElementChild is the element you meant.

innerHTML += in a loop is slow and destructive — it re-parses the whole container each pass and rebuilds every child, losing any state inside. Build a string with map and join, then assign once.

Practice

  1. Build a page with a heading and a list of three items, plus a deferred script. Change the heading's text from JavaScript.
  2. Prove the file does not change. Change the heading, then open View Source and the Elements panel side by side and find the difference.
  3. Get a reference to the list and print its children.length.
  4. Print firstChild and firstElementChild of your list. Explain the difference, and note what firstChild.nodeName says.
  5. From the second list item, reach its parent, its previous sibling and its next sibling.
  6. Use closest('ul') from inside a list item. Then use closest with a selector that matches nothing and confirm you get null.
  7. Assign to the same element's textContent three times in a row and confirm only the last is visible.
  8. Feel the cost. Build a list of 2,000 items two ways — innerHTML += inside a loop, and one assignment after map/join — with console.time around each. Do not guess the difference; measure it. Then type something into an input inside the container and run the slow version again to see what happens to what you typed.

Next: selecting elements properly — the four ways to find a node, and the one that returns a list that changes underneath you.

Stuck on this lesson?

Being stuck is part of it — but being stuck alone for three days is not. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.

About the internship