In this lesson, we'll learn all about the Document Object Model, or DOM and how it became a necessary part of web development. We'll learn how to access and manipulate those elements.
- Define the DOM
- Explain what role the DOM plays in a web page
- Relate HTML elements as Parents, Children and Siblings
- Identify common DOM manipulation patterns:
- query for an element
- edit an element
- add an element
- remove an element
- Use DOM commands to interact with a page
- Fork and Clone
touch app.js
touch index.html
code .
app.js
:
console.log('stranger things are coming!')
index.html
! tab
- to insert html boiler plate- set title to
Hawkins
inside the head
index.html
=> body
:
<h1>
- with the text 'Welcome to Hawkins' 1.<div>
with a class ofcontainer
index.html
=> body
=> div.container
:
<img>
with asrc
ofhttps://londontheinside.com/wp-content/uploads/2017/11/StrangerThings2.png
and analt
ofWelcome to Hawkins
<h3>
with textFeaturing
<ul>
<ul>
<li>Hawkins National Laboratory</li>
<li>Hawkins Police Station</li>
<li>Bradly's Big Guy Supermarket</li>
<li>Melvad's General Store</li>
<li>The Palace Arcade</li>
</ul>
- Inside the
head
tag addsrc tab
to add ascriptsrc
link theapp.js
<script src="app.js" charset="utf-8"></script>
-
Load
index.html
in the browser -
command option j
to open Chrome Developer Console -
Our html
- Expected appearance:
- We can also draw our HTML as a tree, with the
document
as the parent, and then have relations of parent and children relationships and sibling relationships
- The
head
andbody
are children of thedocument
- The
body
is the parent element toh1
and thediv
with a class ofcontainer
- The
h1
element and thediv
element are siblings - Additionally the
li
elements are also siblings or each other - what relationship does the image have with the
h3
? What about the image and thediv
with the class ofcontainer
?
Being able to relate the different elements in this way is often referred to as 'traversal' and there are JavaScript methods that will help you access the element you want. Oftentimes you'll want to target the child elements or the parent element, rather than the element itself. This will become more apparent as you start to build more complex things.
The DOM stands for Document Object Model. When we send HTML to a browser, like we did with our mini Hawkins site, the browser renders the HTML (displays it in a window) and it also creates a giant object that represents the web page. If you are a fan of Stranger Things, you could almost think of the DOM as The Upside Down, a parallel world that is only visible to some (and also, not evil).
As web developers, we can interact with this object (DOM) and we can make changes to the DOM, the browser will then redraw the web page to reflect the changes we made to the DOM.
Open the console in Chrome Developer Tools:
Ctrl Command J
All web pages start with the root of document
.
As we start to type document
in the Chrome console, we see it can be autocompleted because it exists
We can go one deeper into the body (don't forget to press the up key to get your previous line)
And deeper
We can see that the children of the body are an h1, element, a div with a a class of container:
We can keep traversing downward..
This way of accessing elements in the document requires a LOT of typing and always mapping out your web page. And if you change anything one around on your page, the route will likely break (great example of fragile code). So if you moved the h2 element above the image it would be
document.body.children[1].children[0].innerText
Instead of hard-coding our access to different elements, the browser has some built in methods to find the element we are looking for. It's called querying
So we can query the document
for the h1
element and change the text inside (referred to as a key-value property of innerText
) this element. When we change it in the DOM it will also update the browser view.
document.querySelector('h1').innerText = 'Welcome to the Upside Down';
As we can see as we've updated the DOM in the console, it has also updated our view in the web page.
** Bonus **
We can go to any website, like MDN, look for a specific header and change it to say Everyone agrees, General Assembly is the Best!
- however, will our changes be permanent? Will we get in trouble with MDN? You could also think about how a Chrome extension could target(query for) ads and hide them.
Let's refresh our page (remember: command r
also, sometimes you need a hard
(clears some cached things) refresh you can do that with command shift r
) and see that we've switched back to Hawkins. Whatever changes we make in the Chrome console, aren't permanent.
We can also manipulate the DOM from a js
file
Let's grab that code from above and put us back in the upside down:
document.querySelector('h1').innerText = 'Welcome to the Upside Down';
Uh oh! It didn't work:
This is because the document is being read from top to bottom and our JavaScript is running before our h1 has loaded.
There are a couple ways to solve it. For now, let's move our link to our app.js
to be right before the closing body tag:
Now, when we refresh our page, we should see our updated h1
.
- JavaScript was built to manipulate the DOM
- Early JavaScript was challenging to use for complex projects, and although all the basic functionality was built in, creating solutions could be verbose and clunky
- jQuery is a JavaScript library that was created to make manipulating the DOM easier. It built a lot of useful functions and made JavaScript for the DOM easier to write. Some say that it is better than Vanilla JS.
- JavaScript has been changing and a lot of better functionality has been built in. Some people would argue that now JavaScript is a superior solution over jQuery. Use the tool that works best for you.
It is a common pattern to query for an element and then store it in a variable for reuse
- Let's query for the image
const image = document.querySelector('img')
Instead of querying over and over again, we now have our image stored in a variable. Let's console.log it!
console.log(image)
Sometimes you want to add or remove a class to change the appearance. Sometimes you want to change it inline with JavaScript - for now let's do it inline:
We can now manipulate our image:
Let's make it disappear!
image.style.display = 'none'
Let's make it reappear!
image.style.display = 'block'
Let's make it black and white
image.style.filter = 'grayscale(100%)'
Let's set the width to 95%
image.style.width = '95%'
Finally, let's make it color again
image.style.filter = ''
There are tons of different things you can do. The important thing to note is how easy it is to reuse a queried element and manipulate it when you store it to a variable.
We can create a new element
Let's create a new image
const eggos = document.createElement('img')
Where is it?
Although we created the element, we haven't appended it anywhere to the DOM.
Let's add those eggos to the div
with a class container
.
document.querySelector('.container').appendChild(eggos)
Yeah, wait! Where is our image? We can see the tag is appended after the ul
in Chrome console:
But it has no attributes. We have to give it a src
attribute with an image
Many elements have attributes, you can add, edit and remove them using JavaScript as well.
eggos.setAttribute('src', 'https://i.ytimg.com/vi/TgSmPqMGk2g/maxresdefault.jpg')
Oh! They are huge! Let's shrink them down a bit
eggos.style.width = '50%'
- you could also target this element and style it in a css file
Getting rid of an element is easy!
eggos.remove()
What if we have more than one element of the same kind?
We have a few list items let's grab them!
document.querySelector('li')
Right on! We only got our first element!
To get all of our elements, we have to use a different method
document.querySelectorAll('li')
Now we get a NodeList
This list is like an array - So we can access the first li ("Hawkins Laboratory") and change its text to be "Demo Dog Hangout"
document.querySelectorAll('li')[0].innerText = 'Demo Dog Hangout'
Hopefully all those drills of accessing objects and things within the objects is helping us understand how we can access the DOM
Let's try a different one
document.querySelectorAll('li')[4].style.color = 'hotpink'
What did we change there?
Last one: Let's remove Melvad's
When we remove it, will The Palace Arcade lose it's new color?
document.querySelectorAll('li')[3].remove()
DOM commands fall into a few broad categories:
- Search / retrieval of elements on the page
- Creating new elements
- Editing the DOM
- Traversal (related to search) - navigating the DOM
We will only need a small handful of these commands for now. Here is a sample:
-
Search
- document.querySelector()
- document.getElementById()
- document.getElementsByClassName()
- document.getElementsByName()
-
Creation
- document.createElement()
- node.style
-
DOM editing
- node.appendChild()
- node.removeChild()
- node.innerText
- node.setAttribute()
- node.innerHTML
- node.id
- node.classList
-
Traversal
- node.childNodes
- node.children
- node.firstChild
You might be asking: what is a node?
A node is the generic name for any type of object in the DOM hierarchy. A node could be one of the built-in DOM elements such as document or document.body, it could be an HTML tag specified in the HTML such as <input>
or <p>
or it could be a text node that is created by the system to hold a block of text inside another element. So, in a nutshell, a node is any DOM object.
Information about nodes was gathered from here
We learned all about the Document Object Model and it's structure. We learned how to access those elements with relative selection, as well as through query selectors.