Intro to the DOM

Learning Objectivesβ
Students Will Be Able To: |
---|
Use DevTools to Explore the DOM |
Select a Single Element in the DOM |
Select Multiple Elements in the DOM |
Change the Content of an Element |
Change the Style of an Element |
Manipulate the Attributes of an Element |
Manipulate the Classes of an Element |
Iterate Over a Collection of Elements |
Road Mapβ
- Setup
- What's the DOM?
- Using DevTools to Explore the DOM
- Selecting DOM Elements
- Selecting a Single Element by its
id
- Selecting a Single Element Using a CSS Selector
- Changing the Content of an Element
- Changing the Style of an Element
- Accessing/Modifying the Attributes of an Element
- The
class
Attribute - Selecting Multiple Elements
- DOM Selection Summary
- Iterating Over a Collection of Elements
- Further Study
Videosβ
1. Setupβ
Today we will use an actual project structure instead of working within Replit.
Create the Project Filesβ
- Make sure you are in your root directory:
cd ~
- Make a
code
folder (if you haven't yet):mkdir code
- Move into your
code
folder/directory:cd code
- Create a new directory named
dom-practice
:mkdir dom-practice
- Move into the new directory:
cd dom-practice
- Create an
index.html
file:touch index.html
- Open the directory in VS Code:
code .
- Open
index.html
in the editor and use! [tab]
to create the HTML boilerplate - Create a
js
directory and touch ajs/main.js
file - Add a
<script>
tag to includemain.js
in the<head>
:
<head>
...
<title>DOM Practice</title>
<script defer src="js/main.js"></script>
</head>
The
defer
attribute ensures the DOM is ready before the script executes.
- Finally, let's add an
<h1>
inside of the<body>
as follows:
...
<body>
<h1 id="title" class="main-title">DOM Practice</h1>
</body>
</html>
Note: It's a best practice to use double quotes and kebab-casing in HTML.
View index.html
in Live Serverβ
In order to view the index.html
page in the browser, we're going to install a popular extension in VS Code called Live Server.
Click on the Extensions icon in VS Code's activity bar:

Type "Live Server" into the Search input and click the green [Install]
button for the top Live Server result as shown:

To return to the file explorer, click the icon in the top-left, then, to start Live Server, click "Go Live" in the status bar at the bottom:

Live Server should automatically open index.html
in a new browser tab:

2. What's the DOM?β
The DOM (Document Object Model) is the in-memory data structure that represents the browser's web document.
As you can see, it's a tree-like data structure with the top (root) being the document
object.
β What JS data type would each of those nodes be?
Nodes most certainly will be JS objects with properties used to get/set information and methods to manipulate the DOM.
If we type document
in DevTool's console, we'll see the HTML-centric representation of the document, however, we want to explore the JavaScript data structure that is the DOM. We can do this by typing dir(document)
in console and exploring the objects and properties of the DOM.
The DOM has an application programming interface (API) that enables developers to make the UI dynamic by using JavaScript to:
- Add/remove elements to/from the document
- Change the content of elements
- Change an element's styling
- Listen for events, e.g., when an element is clicked
- Animate elements
3. Using DevTools to Explore the DOMβ
After index.html
is opened in Chrome, use the keyboard shortcut of option command J
(macOS) or ctrl shift J
(Windows) to open Chrome's DevTools.
Click on the Elements tab to browse the HTML hierarchy of the DOM.
Let's try out the DevTools by clicking on the h1
element and using the Styles panel to add a CSS property of color: red;

Look closely after the closing </h1>
tag - you see that == $0
?
That tells us that Chrome has created a variable named $0
that represents the <h1>
element in the DOM!
Click on the Console tab and let's explore the properties on the $0
element/object by typing dir($0)
.
You are now able to explore the <h1>
element's DOM object - referred to as a node.
Now try typing this in: $0.style.backgroundColor = 'yellow'
CSS property names in the DOM are lowerCamelCased because hyphens would be interpreted as minus signs.
4. Selecting DOM Elementsβ
Developers make web pages dynamic by manipulating the DOM using JavaScript.
For example, in a To-Do app, a user typically would:
- Type the text of the new to-do into an
<input>
- Click an
[Add Todo]
<button>
The developer certainly would have coded a JavaScript function that would run in response to the button being clicked.
That function would then perform the following:
- Create a new element, e.g., an
<li>
- Access the text entered into the
<input>
element - Set the content of the
<li>
to that text - Append the new element to the appropriate parent element, e.g., a
<ul>
- Finally, for a better user experience (UX), "reset" the input by clearing out the current text
Several of the above steps requires the JS to access existing elements. Let's see how we can select those DOM elements...
5. Selecting a Single Element by its id
β
The getElementById method is the most efficient way to select a DOM element if it has an id
assigned to it (using the id
attribute).
Let's select the <h1>
by its id
and save the reference to the DOM element in a variable named titleEl
:
const titleEl = document.getElementById("title");
console.log(titleEl);
If you wish to explore the element's JS object representation (the DOM), use console.dir()
instead of console.log()
.
Note: When using
getElementById
, be sure not to preface the name of the id with#
, e.g.,document.getElementById('#title');
will returnnull
!
Cool, but how do we select a single element without an id
? Let's see...
6. Selecting a Single Element Using a CSS Selectorβ
The querySelector(selector) method is the go to method for selecting a single element using the power of CSS3's selectors.
The selector
argument is a string that follows the rules of regular CSS3 selectors.
Yes, we can select DOM elements using CSS3 selectors just like do to target elements for styling!
β What selector would be used to select a <section>
element with a class of main
?
<section>
element with a class of main
?section.main
If the CSS selector provided to querySelector()
matches multiple elements, it returns the "first" matching element, however, it's best to avoid this scenario by using a more specific selector.
If no matching DOM element is found, querySelector()
will return null
.
π YOU DO: Practice (3 mins)β
-
In
index.html
, add a<p>
tag below the<h1>
and give it aclass
ofcool
, then... -
Add some content inside of the
<p>
tag - try typinglorem [tab]
to emit (using emmet) random lorem ipsum text. -
Use
document.querySelector()
to select the<p>
element with a class ofcool
and assign it to a variable namedpEl
. -
Verify that the
<p>
element was selected by logging outpEl
.
7. Changing the Content of an Elementβ
Now that we're able to select an element of our choosing, let's see how we can change the content of that element...
Inspecting the properties of a DOM element in the console reveals a couple of properties that we can use to read and set its content:
- innerHTML - Used to retrieve/set content as an HTML string
- innerText - Used to retrieve/set content as plain text
Let's check out changing the content of the <p>
element by assigning the string Comments for <strong>Today</strong>
first to innerText
, then to innerHTML
.
As you saw, if you want to include HTML in the content, use innerHTML
.
The power of innerHTML
may not be obvious at first, however, the string being assigned can be as complex as you want - containing multiple elements with attributes, etc.
If the string you want to assign does not contain any HTML, assigning to innerText
is more efficient. This way, JS knows that it doesn't need to scan the string, looking for some HTML to process.
Note: There is another property, textContent, that is very similar to
innerText
- the primary difference between the two is that:textContent
returns all text content regardless of (CSS) styling, whereasinnerText
takes any styling into consideration. For example,innerText
won't return text that has been hidden using CSS.
8. Changing the Style of an Elementβ
DOM elements have a style property that can be used to set CSS styling!
Check out the CSS properties in the console.
β What naming convention is used for CSS properties in the DOM?
lowerCamelCasing
β What naming convention is used for CSS properties in CSS?
kebob-casing
β Why can't kebob-casing be used for the DOM as well?
The DOM is JS so the hyphen would be interpreted as a minus sign
This is how we can center the text in the <h1>
by setting the text-align
CSS property on the style
object:
const titleEl = document.getElementById("title");
titleEl.style.textAlign = "center";
π YOU DO: Setting Styling on a DOM Element (1 min)β
- Change the
color
of the<p>
element to a color of your choosing.
9. Accessing/Modifying the Attributes of an Elementβ
You may need to get, set, or check if an element has a certain attribute.
The following are methods that the Element API has for working with an element's attributes:
π YOU DO: Attributes (5 mins)β
-
In
index.html
, add an<a>
element toindex.html
with content of "Visit Google" but without anhref
attribute. -
Reload the page and verify that the link does not work. In fact, it won't even look like a link.
-
In the JS, write the line of code that will add an
href
attribute that will make the link navigate tohttps://www.google.com
.
Hint: Which of the attribute methods above looks tasty?
10. The class
Attributeβ
Technically, you could use those attribute methods above to work with an element's classes.
However, the classList property offers a better approach.
classList
is an object with the following methods pertaining to classes:
add(className, className, ...)
remove(className, className, ...)
toggle(className)
contains(className)
replace(oldClass, newClass)
β Review Questionsβ
(1) If we want to change the text (without HTML) inside of a <div>
, which property should we assign to?
<div>
, which property should we assign to?innerText
(2) How many DOM elements are returned by the querySelector
method?
querySelector
method?one
(3) What DOM element property is used to style a DOM element using JS?
style
11. Selecting Multiple Elementsβ
Before we check out selecting multiple elements, let's add the following HTML below the existing <p>
element.
VS Code includes Emmet, which is a great tool for quickly generating markup. Type the following to generate most of the desired markup below:
ul#comments>li{comment}*3
<ul id="comments">
<li>first comment</li>
<li>second comment</li>
<li>third comment</li>
</ul>
Like querySelector()
, the querySelectorAll(selector) method uses the power of CSS3 selectors to specify which DOM elements we want to select.
Of course, like the name says, it selects all DOM elements that match the provided selector.
π YOU DO: Selecting Multiple Elements (2 mins)β
-
Use
document.querySelectorAll()
to select all<li>
elements that are children of the element with an id ofcomments
, assigning them to a variable namedcommentEls
. -
console.log(commentEls)
to verify it worked.
12. DOM Selection Summaryβ
In summary, use the following to help you decide which method to use to select DOM elements:
-
getElementById
: Use when you need to select a single element that has anid
assigned to it. -
querySelector
: Use when you need to select a single element that does not have anid
. -
querySelectorAll
: Use when you need to select multiple elements.
13. Iterating Over a Collection of Elementsβ
querySelectorAll
returns an array-like object called a NodeList.
There are three approaches we can use to iterate over the elements in a NodeList:
-
A regular for loop: This works, but it's not as readable or elegant...
-
The NodeList's forEach method: A good option when you want to iterate through all elements and/or need to access the index of the iteration.
-
A for...of loop: Elegant and allows early exit of the loop with the
break
statement. However, if we need to access the index of the iteration, we would need to track it manually by initializing a separate variable before the loop and incrementing it within the loop.
Let's type the following for...of
loop in the console to log each element:
for (let commentEl of commentEls) {
console.log(commentEl);
}
Now let's use the same for...of
statement to modify those comment elements...
π YOU DO: Iterating and Updating Styling (3 mins)β
- Add a
for...of
loop tomain.js
that changes the font size of all the<li>
comment elements to30px
.
Hint: You must use a string like
'30px'
- just the number30
or the string of'30'
will not work.
14. β Essential Questions (3 mins)β
(1) What method is the most efficient for selecting an element that has an id
?
id
?getElementById
(2) If we want to assign content to an element that includes HTML, what property on the DOM element would we assign to?
innerHTML
(3) If we want to assign plain text (no embedded HTML), what property on the DOM element would we assign to?
innerText
(or textContent
)
(4) Which property on a DOM element is used to set the CSS styling for that element?
style
15. Further Studyβ
Turning NodeList
& HTMLCollection
Array-Like Objects Into Actual Arraysβ
As discussed in the lesson, methods designed to return a collection of DOM elements return "array-like" objects that have a forEach
method, but don't contain other useful methods that full-fledged arrays have.
If you would need to hold your DOM elements in an actual array, either of the following two approaches will do the trick...
Array.from()
Methodβ
Here's how you can use the Array.from static method to convert an iterable, such as a NodeList, into an actual array:
const itemEls = Array.from(document.querySelectorAll(".item"));
Now, itemEls
would be an actual array with all array methods available.
For example, here's how you could find the index of a clicked DOM element in the array:
const itemEls = Array.from(document.querySelectorAll(".item")); // puts all returned elements into an array
const containerEl = document.querySelector("section"); // selects the first <section> tag
containerEl.addEventListener("click", handleClick); // attaches a click listener/handler to the <section> element
function handleClick(event) {
const indexOfClickedItem = itemEls.indexOf(event.target); // returns the array index of the item clicked
console.log(indexOfClickedItem);
}
βWhat is event? What is event.target? The event interface is an extremely useful tool that will help provide us with the properties of the element being acted upon.
Spread Syntaxβ
Another way to convert a NodeList or HTMLCollection into an array is by using the Spread Syntax within an array literal:
const itemEls = [...document.querySelectorAll(".item")];
Other Methods to Select Multiple Elementsβ
The following methods can also be used to select multiple elements:
getElementsByTagName(namesString)
getElementsByClassName(namesString)
The above methods return a live HTMLCollection.
Although it's pretty cool that the returned list is automatically updated to include/exclude DOM elements as the DOM changes, the above methods are not as flexible as the querySelectorAll
method.