Lesson 1
Mastering Advanced Document Object Model (DOM) Manipulation Techniques
Overview

Welcome to our lesson on web development using the Advanced DOM and Browser APIs. Our focus will be to understand the Document Object Model (DOM) and its relationship with JavaScript for manipulating web pages. We'll see how parentNode, nextSibling, previousSibling, firstChild, and several others can be used to navigate and alter the DOM as we aim to create dynamic web pages.

Learning the DOM is essential; it extends our power to dynamically add, delete, and change elements and content on a webpage, making it not only interactive but also responsive to user actions. For instance, consider a shopping website displaying a running total of items in your cart or a weather site updating real-time temperatures!

Understanding the DOM Tree Structure

Let's introduce the DOM Tree structure using a simple HTML document.

Here's an example HTML document:

HTML, XML
1<!DOCTYPE html> 2<html> 3<head> 4 <title>Page Title</title> 5</head> 6<body> 7 <div id="parent"> 8 <p>Paragraph 1</p> 9 <p id="middle">Paragraph 2</p> 10 <p>Paragraph 3</p> 11 </div> 12</body> 13</html>

We can picture the structure of the HTML document as a tree diagram, known as the DOM Tree. Each HTML element, including the text inside other elements, becomes a node in this tree. This diagram gets us closer to visualizing the DOM Tree:

1 document 2 | 3 html 4 / \ 5 head body 6 / \ 7 title div 8 / | \ 9 p p p

Now, let's look at properties that help us navigate this tree. The parentNode property returns the parent of the specified node, and the firstChild property accesses the first child of a node. You can also traverse to the neighboring nodes on the same level using nextSibling and previousSibling. Utilizing these properties, we achieve a successful traversal of the DOM Tree. Here's an example:

JavaScript
1let parent = document.getElementById("parent"); 2console.log(parent.firstChild); // Logs "Paragraph 1" node 3 4let middle = document.getElementById("middle"); 5console.log(middle.parentNode); // Logs the parent "div" node 6console.log(middle.previousSibling); // Logs "Paragraph 1" node 7console.log(middle.nextSibling); // Logs "Paragraph 3" node

Navigating the DOM Tree allows you to access nodes dynamically. Up next, we'll discuss finding specific elements within the tree.

Accessing Elements in the DOM: Part I

To interact with elements on a webpage, we first need to locate or select these elements in the DOM. JavaScript provides several methods to do this: getElementsById, getElementsByTagName, and getElementsByClassName.

Consider an HTML document:

HTML, XML
1<!DOCTYPE html> 2<html> 3<body> 4 <h2 id="title" class="header">Hello World!</h2> 5 <p class="paragraph">This is a paragraph.</p> 6 <p class="paragraph">This is another paragraph.</p> 7</body> 8</html>

The getElementById('title') will return the <h2> element since it has an id of 'title'. getElementsByClassName('paragraph') will return a collection (an array-like object) of all elements with the class 'paragraph', in this case, both <p> elements. getElementsByTagName('p') will similarly return both <p> elements:

JavaScript
1console.log(document.getElementById("title")); // Logs <h2> element with id="title" 2console.log(document.getElementsByTagName("p")); // Logs all <p> elements 3console.log(document.getElementsByClassName("paragraph")); // Logs all elements with class="paragraph"
Accessing Elements in the DOM: Part II

In addition to the methods mentioned above, JavaScript provides querySelector and querySelectorAll which use CSS selectors to locate elements.

The querySelector method returns the first element that matches a specified CSS selector(s), while querySelectorAll returns all elements that match the CSS selector(s) in a NodeList object.

What makes these two methods even more powerful is that they can accept multi-level CSS selectors.

Consider this HTML structure:

HTML, XML
1<!DOCTYPE html> 2<html> 3<body> 4 <div id="parent"> 5 <p class="child">Child 1</p> 6 <p class="child">Child 2</p> 7 </div> 8</body> 9</html>

In our script, we can use querySelector and querySelectorAll with multi-level CSS selectors to target specific elements. For instance, querySelector('#parent .child') will select the first <p> element with the class child that is a child of the element with the id parent.

JavaScript
1console.log(document.querySelector("#parent .child")); // Logs the first <p> element with class="child" inside the element with id="parent" 2console.log(document.querySelectorAll("#parent .child")); // Logs all <p> elements with class="child" inside the element with id="parent" 3console.log(document.querySelectorAll("p")); // Logs all <p> elements

Notice that we use CSS syntax for query selectors. Therefore, we put . in front of the class name and # in front of the ID.

These methods allow us to target elements with a high degree of precision, which is incredibly valuable for DOM manipulation. In the following section, we're going to explore how to add or remove elements in the DOM using JavaScript.

Manipulating Elements in the DOM

JavaScript gives us the power not only to access and traverse the DOM but also to modify it. We'll be looking at methods like createElement, appendChild, removeChild, and replaceChild which enable us to create and add new elements, remove existing ones, or even replace one element with another on a webpage.

Consider this simple HTML structure:

HTML, XML
1<!DOCTYPE html> 2<html> 3<body> 4 <div id="parent"> 5 <p id="firstP">Hello, World!</p> 6 </div> 7</body> 8</html>

Let's use JavaScript to manipulate our DOM:

HTML, XML
1<!DOCTYPE html> 2<html> 3<body> 4 <div id="parent"> 5 <p id="firstP">Hello, World!</p> 6 </div> 7 8 <script> 9 // Creating a new paragraph element. Note that it's not in the DOM yet, so we won't see it in the UI yet 10 var newP = document.createElement("p"); 11 var text = document.createTextNode("This is a new paragraph."); 12 newP.appendChild(text); // New paragraph now contains the text. Still not visible in the UI 13 14 // Accessing the parent div with id="parent" and the first paragraph with id="firstP" 15 var parent = document.getElementById("parent"); 16 var firstP = document.getElementById("firstP"); 17 18 // Append the new paragraph to the DOM. Now the parent has two children: 'firstP' and 'newP' 19 parent.appendChild(newP); 20 21 // Remove the first paragraph. Now the parent has only one child: 'newP' 22 parent.removeChild(firstP); 23 24 // Create another paragraph, 'anotherP', and replace 'newP' with 'anotherP'. Now the parent has only one child: 'anotherP' 25 var anotherP = document.createElement("p"); 26 text = document.createTextNode("This is another paragraph."); 27 anotherP.appendChild(text); 28 parent.replaceChild(anotherP, newP); 29 </script> 30</body> 31</html>

This set of operations demonstrates the ability to create, add, remove, and replace elements in a web page. With these skills, you now have control over the DOM! In the next section, we'll reinforce these skills with practical exercises.

Adding Class and ID Attributes with JavaScript

To further manipulate elements in the DOM, JavaScript lets us assign classes and IDs to an element. This is extremely handy when we want to style an element or use it as a unique identifier, especially handling events.

A JavaScript property that corresponds to the class attribute is element.className. With this, we set the class attribute of an element. Similarly, element.id allows us to set the ID attribute of an element. Let's see how these work:

HTML, XML
1<!DOCTYPE html> 2<html> 3<body> 4 <p id="firstP">Hello, World!</p> 5 <script> 6 var firstP = document.getElementById("firstP"); 7 8 // Assigning a class 9 firstP.className = "highlight"; 10 11 // Assigning an ID 12 firstP.id = "para1"; 13 14 console.log(firstP.className); // Logs "highlight" 15 console.log(firstP.id); // Logs "para1" 16 </script> 17</body> 18</html>

In this example, we assigned a class named "highlight" and an ID named "para1" to our paragraph. Now, we could apply CSS styles to the "highlight" class, and those styles would be applied to our paragraph. Similarly, we could use the ID "para1" as a unique identifier for this paragraph whenever required.

Lesson Summary

You've now mastered navigating the DOM Tree, accessing specific nodes, and learned how to add, remove, and replace elements on a web page dynamically. The concepts you've learned in this practical session can be utilized to create tickers on news websites, create and update a user's shopping cart in real-time on an e-commerce site, build forms, image carousels, and so much more.

It's now time for practice to solidify these newly-acquired skills. As you embark on hands-on exercises, remember that mastery comes with practice — go for it!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.