DOM Traversal

DOM is just is another way to move from one part of the DOM to another based on its relationship.

The DOM is something that we already looked in my Working with the DOM blog post. In that post, we used the document object to select our elements. However, you’ll often come across times where you already selected an element but need to select an element nearby. That process is called DOM Traversal.

<div id="text-wrapper">
    <p> This is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>
</div>

<script>
    let paragraph = document.getElementsByTagName('p')[0];
    let parent = paragraph.parentNode;
    parent.removeChild(paragraph);
</script>

You can remove an element from the DOM by using the removeChild method. You need to run this method on the element’s parent. In other words, we need to traverse to the parent. Luckily for us, elements contain a parentNode property that we can use. In our example, we use the parentNode property and assign it to the parent variable. Then we use the parent to remove that paragraph with the removeChild method.

previousElementSibling

With the parentNode giving you the parent of a selected node, there are properties for selecting siblings. If you head over to the Mozilla Develop network it will give us a full breakdown of the previousElementSibling property. The first thing you may ask yourself what the hell does non-document type child node mean? To be honest it’s something you don’t need to worry about its just a big name for the element object. The second question you may have, why is the word element in the previousElementSibling property name whenever we just used node to select the parent? Well, that’s because there is another previousSibling property which is older and has better support than previousElementSibling. But there is an issue with previousSibling property that we can see below.

<ul>
  <li id="item1">Coffee (first li)</li>
  <li id="item2">Tea (second li)</li>
</ul>

<script>
  let li = documentquerySelectorAll('li')[1];
  li.previousSibling;
  li.previousSibling.textConent;
</script>

In the example I’ve declared a variable li and stored a reference to the second li tag. With the last li selected I’ve accessed the previousSibling property that returns something called #text. If you hover over the return #text in your console you’ll notice nothing is highlighted in the DOM as it usually does when selecting elements. To see whats in #text I’ve accessed the textContent property of our previousSibling. If you’ve run this in your console you’ll see its an empty two-line string.

You may be asking to f@*K is going on here? The previousSibling property gets the previous document node, which isn’t always an HTML element, in our example, it’s an empty string that sits between the list items that helps to format the HTML. Because of this, you can’t rely on the previousSibling property to give you the previous element whereas previousElementSibling will always return an element. Let’s see an example.

<ul>
  <li id="item1">Coffee (first li)</li>
  <li id="item2">Tea (second li)</li>
</ul>

<script>
 let li = documentquerySelectorAll('li')[1]; 
 li.previousElementSibling;
</script>

Instead of the previousSibling I’ve used previousElementSibling to return our first list item ‘coffee’. One thing to keep in mind. Just like selecting the previous element, you can also select the next element by accessing the nextElementSibling property. It works exactly like previousElementSibling the only difference being it selects the next sibling element.

Children of a Node

With the children property, you can get all the children elements of a node. If you head over to the Mozilla Develop network it will give us a full breakdown of the property. Basically, when used on a parent element the children property returns an HTML collection of child elements. The elements are sorted as they appear in the source code and like any HMTL collection they can be accessed by an index number eg the first element is referenced by 0. Let’s look at an example.

<!DOCTYPE html> 
<html> 
  <body> 
    <h1>Children Nodes</h1>
    <p>A small demo</p>
    <ul id="elementsList"></ul> 
    <script> 
      let list = document.getElementById("elementsList");
      let children = document.body.children; 
      let elementTagName = ""; 
      for (let i = 0; i < children.length; i++) { 
        let li = document.createElement("LI");
        elementTagName = children[i].tagName; 
        li.innerHTML = elementTagName;
        list.appendChild(li);
      }
    </script>
   </body> 
</html>

In this example, we simply get all of the child nodes inside the body element and add them to our list. One thing to remember there is a similar property called childNodes, the difference being that the childNodes property contains all the nodes including text and comments nodes. This is similar to how previousSibling works and has the same issues in that you can’t rely on it to return HMTL elements so you’ll want to stick with children property to work with the DOM.

The First & Last Child

For the last part of this blog post, the last two properties I wanted to cover is firstElementChild which gives you the first child element of a selected parent element and the second property lastElementChild which as the name says gives you the last. Just as we covered earlier with the previousElementSibling and children properties the firstElementChild and lastElementChild properties have older properties called firstChild & lastChild. And the issue with the older properties is the same in that they don’t always return HTML elements. The firstElementChild and lastElementChild should be pretty easy to understand after what we’ve covered but let’s take a look at an example.

<!DOCTYPE html> 
  <html> 
    <body> 
      <ul id="shopping-list">
       <li>coffee</li>
       <li>more coffee</li>
       <li>different coffee</li> 
      </ul> 
      <script> 
        let list = document.getElementById("shopping-list"); 
        let firstChild = list.firstElementChild;
        let lastChild = list.lastElementChild;
        
        firstChild.style.backgroundColor = "red";
        list.removeChild(lastChild);
      </script> 
    </body> 
 </html>

In this example, we get the first and last child elements from our ul element. We changed the background colour for the first child and removed the last child because we had too much coffee. To do this we first create a few variables, the first variable ‘list’ is to store our ul element and selected with getElementById, the second variable firstChild, is to store the first child of our ul by accessing firstElementChild property on our list element, and the third variable lastChild we store the last child of our ul by accessing the lastElementChild property on our list. Once we have the first & last elements we can start to make the changes. With the firstChild, I wanted to highlight the important item by highlighting the list item by changing the background color via the style property. With the lastChild I’ve too much coffee on the list so I just wanted to remove it by using the removeChild method on our list and passing it the element we want to remove, in our case the lastChild.

Wrapping Up

In this post, we’ve learned a lot about traversing the DOM with Javascript. These are just the basic’s head over MDN network to learn even more. Thank you for reading, and being part of the discussion. If you would like to chat or have any questions drop me an email I’m always happy to talk.