Traversing the DOM with JavaScript
Traversing the DOM might sound daunting at first because of its relational nature. It might even seem like it’s unnecessary to traverse the DOM because we can just use query selectors to get around and find elements. However, traversing the DOM can be faster and more efficient than using query selectors.
What is the DOM?
The DOM or Document Object Model is the reference point for elements on a web site; the location of elements are the nodes of the DOM tree. These nodes correlate to the type of element that they represent. The DOM therefore by definition closely follows the HTML layout of the page. When we traverse the DOM tree we can go up and down it from any node on the tree. This makes DOM traversal very powerful and gives us access to elements that we might not have otherwise.
Traversing the DOM
When we traverse the DOM we can go both up ,down or sideways on the tree however, we do need to follow the branches of a tree to get to a specific node. Elements can be described as parents, children, or siblings. Parents as the name suggests are referenced when we traverse upwards, children are when we traverse downwards, and siblings are used when traversing sideways. We can access these nodes as node objects.
Traversing upwards
When traversing upwards we can access any node that is above of the node we are currently in or have access to. These nodes are also known as ancestor nodes. We can use the following methods:
- .parentElement
- .parentNode
- .closest
Both .parentElement and .parentNode help us to traverse upward to the “parent” element in the DOM. This is the element or node that is directly above or one level up the element we are currently in. An element can only have one parentNode; the one directly above it.
//example of the syntax
//.parentElementconst parentItem = Item.parentElement
.closest is an extremely useful method that allows us to find the closest ancestor element that matches a selector. This method has the ability to go all the way up the DOM tree to find any element that matches the description. This can include IDs, classes, tags, and element types.
//example of the syntax
//.closestconst closestAncestor = Element.closest("selector")//selector types examples:
-div
-id
-class
-li
-p
Traversing downwards
When traversing downwards we are going to use child selectors which makes sense because a parent has children. However, unlike a parentNode a parent can have many childrenNodes. We can use the following methods to traverse downwards:
- .childNode
- .children
- .firstChild
- .lastChild
These child selectors basically do the same thing with one difference which is .childNode only returns one element; which is the first child element but .children return all the children of a particular parent. .firstChild and .lastChild returns the first and last child respectively. All of these methods have their own specific use cases.
//example of syntax
const childElements = list.children;//this lists all of the DOM Nodes that come after the list elementconst childElement = list.childNode
//only lists the first child node
Traversing sideways
Traversing sideways is probably the most difficult to understand because it is harder to visualize what is occurring on the DOM tree. Siblings are elements that are on the same “level” on the tree i.e. across. Parents and Children are fairly self explanatory but siblings require both a upward and downward transversal of the DOM tree; even though we have methods that make this easy for us. Two methods we can use are:
- .nextElementSibling
- .previousElementSibling
We can use both of these methods to traverse to the sibling elements of the DOM. .nextElementSibling allows us to select the next element that is a sibling in relation to the element we are currently in and .previous does the same thing but as the name suggests the previous one.
//example of syntaxconst nextElem = Node.nextElementSibling
There are more methods that were not covered in this post but, with this understanding and a little help from the documentation we can traverse the DOM fairly easily and unlock more possibilities when trying to manipulate the DOM with JavaScript.