Table of Contents
An intro to the DOM
Open with f12 or by right-clicking and selecting inspect.
The Chrome Developer Tools allow us to interact with the source code of the page. We can
- Use the Elements tab to view and manipulate the DOM
- Use the Console tab to view
console.log
messages printed from the JS - Use the Network tab to view loaded assets
There are lots of ways to add a script we'll go over later, for now this is easiest
<body>
<!-- other html code -->
<!-- Put this just before the end of the body -->
<script src="./index.js"></script>
</body>
In that index.js
file, place a console.log
statement and view it in the Console tab of the Chrome Developer Tools each time you reload the webpage.
Try the following code:
const fruits = [
{ name: 'apple', color: 'red' },
{ name: 'banana', color: 'yellow' },
{ name: 'mango', color: 'orange' },
];
// Use the arrows to pop open objects
console.log('click to expand!', fruits);
// can do tricks the node console can
console.table(fruits);
Q: Why does the script
tag need to go at the end of the body?
The DOM is the Document Object Model. It is representation of the HTML structure of your website in a JavaScript object format.
For example, consider this HTML:
<h3 id="main-list-heading">Wow a list!</h3>
<ul id='my-list'>
<li class="special-item">Here's an item in the main list</li>
<li>Oh wow another one in main list</li>
<li>And main list item</li>
</ul>
The DOM would take the elements of this HTML structure and turn them into objects! (This is not actually happening in your code. This is just to demonstrate the idea.)
const h3 = {
id: "main-list-heading",
textContent: "Wow a list!"
}
const ul = {
id: "my-list",
children: [
{
class: 'special-item',
textContent: "here's an item in the main list"
},
{
textContent: "Oh wow another one in main list"
},
{
textContent: "And main list item"
}
]
}
The browser automatically generates this document object model for us! As web developers, we can use this DOM to do so much!
Let's dive in.
The document
object is the DOM packaged in an object. The properties of the object allow us to access various elements of the DOM. Each element is a node in the document tree and each node has a .children
array.
console.log(document);
console.log(document.body);
console.log(document.body.children);
console.log(document.body.children[0]);
The document
object also has methods that allow us to perform CRUD operations on the DOM:
- Create new elements (create new "nodes" in the tree)
- Read (find or "query for") existing elements
- Update existing elements
- Delete existing elements
There are many ways to find an Element in the DOM, but querySelector
is the most flexible. It uses CSS selector syntax
// returns the first p tag Element in the document
const firstP = document.querySelector('p');
// get the first Element belonging to the special-item class
const special = document.querySelector('.special-item');
// get the Element with the id main-list-heading
const heading = document.querySelector('#main-list-heading');
// get the first li Element inside the ol
const firstOrderedListItem = document.querySelector("ol > li:nth-child(1)")
More Reading: w3Schools
Once an Element is grabbed from the DOM, we can modify it, and even delete it!
const heading = document.querySelector('#main-list-heading');
heading.innerText = 'hello world!';
heading.id = 'blahblah';
heading.classList = "vivid purple";
// we don't always need to store the element in a variable to do something with it
document.querySelector("ol > li:nth-child(1)").remove();
More Reading: w3Schools
Sometimes we may want to apply a change to multiple elements at once. Use document.querySelectorAll()
to grab multiple elements
// get all li Elements in a NodeList
const listItems = document.querySelectorAll('li');
// get all Elements with the class special-item
const specialItems = document.querySelectorAll('.special-item');
querySelectorAll
returns a NodeList
which is NOT an array. You can use bracket notation but you can't use normal Array methods.
// forEach does work...
const listItems = document.querySelectorAll('#recipe-list > li');
listItems.forEach((listItem) => {
listItem.classList.add('recipe-step')
})
// But other methods dont... --> ERROR: listItems.slice is not a function
listItems.slice(0, 2);
// Spread into an Array first!
const firstThree = [...listItems].slice(0,2)
The pattern:
- Create:
const newEl = document.createElement('div')
- Modify: add an id, class, and text, whatever
- Add:
parentEl.append(newEl)
// 1. Create
const newLi = document.createElement('li');
// 2. Modify
newLi.innerText = 'i love coding!';
newLi.classList.add('special-item');
// 3. Add
const ul = document.querySelector('ul'); // the parent
ul.append(newLi);
You can also insert HTML directly using .innerHTML
but you should be very careful about doing this. Only ever do this if the content you are adding is hard-coded (not user-generated).
const ul = document.querySelector('ul');
ul.innerHTML = `
<li>coding</li>
<li>basketball</li>
<li>soccer</li>
`;