Skip to content
Topic 1 of 5
Theory

Page Elements

What the DOM is

When the browser opens a page, it reads the HTML and builds a tree of objects from it — the DOM (Document Object Model). Every tag becomes an element object: it has text, attributes, classes and children. JavaScript can find any element of this tree and change it — the browser immediately redraws the page.

<body>
  <h1 id="title">Shop</h1>
  <ul class="menu">
    <li>Home</li>
    <li>Catalog</li>
  </ul>
</body>

For this HTML the tree looks like this: body → h1 and ul, and ul has two li. The entry point to the tree is the global object document.

In this course the code runs right on the page to the right: the task already has HTML, and your JavaScript is connected to it like a script.js file on a real website. Press "Run" — you'll see the result in the "Preview" window, and everything console.log prints will appear in "Output".

Finding an element: querySelector

document.querySelector(selector) returns the first element that matches a CSS selector, or null if there is none. The selectors are the same as in CSS:

document.querySelector("#title");      // by id
document.querySelector(".menu");       // by class
document.querySelector("li");          // by tag — the first li on the page
document.querySelector(".menu li");    // li inside .menu
document.querySelector("input[type=email]"); // by attribute

There is also an older way — document.getElementById("title") (without the hash). It is just as fast, but querySelector is more universal, so we'll use it from now on.

If the element doesn't exist, you get null, and trying to change its text will fail with the error TypeError: Cannot set properties of null. If you see this error — check your selector.

Finding all: querySelectorAll

document.querySelectorAll(selector) returns all matching elements — a NodeList collection. You can loop over it with for…of, get its length with .length, or turn it into an array with [...list] to use map and filter:

const items = document.querySelectorAll(".menu li");
console.log(items.length);  // 2

for (const li of items) {
  console.log(li.textContent);
}

const names = [...items].map((li) => li.textContent);
console.log(names);

Output:

2
Home
Catalog
["Home","Catalog"]

You can search not only the whole document but also inside an element you've found: menu.querySelectorAll("li") searches only among the descendants of menu.

Element text: textContent

The textContent property is all the text inside an element (without tags). You can read it and write it:

const title = document.querySelector("#title");
console.log(title.textContent);   // Shop
title.textContent = "Toy Shop";

Text from the DOM is always a string. If it holds a number and you need to calculate, convert it: Number(el.textContent). You can also write a number — the browser turns it into a string by itself.

HTML inside: innerHTML

innerHTML is the content of an element together with tags. When you write a string into it, you replace everything inside the element with new markup:

const box = document.querySelector("#box");
box.innerHTML = "<b>Bold</b> and <i>italic</i>";
box.innerHTML = "";   // quickly clear the element

Important: never insert text typed by the user through innerHTML. If it contains <img src=x onerror="...">, the browser will run someone else's code — this is an XSS vulnerability. For text always use textContent: it shows the string as is, and tags don't turn into elements.

Input field values

For <input>, <textarea> and <select> fields, the text the user typed is not in textContent but in the value property:

const nameInput = document.querySelector("#name");
console.log(nameInput.value);     // what was typed into the field
nameInput.value = "Anna";         // write into the field

For a checkbox you look at checked instead (true / false).

When the script runs

On a real website a script is usually included at the end of <body> or with the defer attribute — then by the time it runs, all the HTML has been read and the elements will be found. If the script is in <head> without defer, querySelector returns null: the elements don't exist yet. On this site the task page is always ready before your code runs.

Summary

  • document is the entry point to the page tree.
  • querySelector — the first element matching a selector (or null), querySelectorAll — all of them.
  • textContent — an element's text, innerHTML — markup (not for user input!), value — a field's value.
  • Text from the DOM is a string; convert numbers with Number(...).

New Heading

Easy+10 XP

The page has a heading <h1 id="title">. Find it and change its text to Hello, DOM!.

Before: Old title
After:  Hello, DOM!

Connect the connector to solve tasks

Task code runs on your own computer — faster and more reliable than in the browser. This needs the free CodeWithMe connector app. You only connect it once.

Looking for the connector on this computer…

  1. 1
    Download the connector for your system (Windows, macOS or Linux).Download the connectorOn the download page pick the file with your system in its name, e.g. windows-amd64.
  2. 2Run it and choose a folder for your solutions. It will install Python and Node.js there by itself when needed.
  3. 3
    Enter below the 6-digit code shown in the connector window (“Code for CodeWithMe”). If the browser asks about local network access — allow it.

The connector is open source (on GitHub), works only on your computer and runs code only after you enter the pairing code.