Lesson Description

The "DOM Traversal" Lesson is part of the full, Getting Started with JavaScript, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Kyle introduces DOM traversal in the lesson. He explains how to move around the DOM structure using concepts like parent elements, children, and siblings. He demonstrates how to use methods like querySelector, next/previous element sibling, and closest to efficiently navigate through the DOM tree. Kyle emphasizes the importance of using flexible methods like closest and querySelector over parent element and children for more robust code that adapts to changes in the HTML structure.

Preview

Transcript from the "DOM Traversal" Lesson

[00:00:00]
>> WebDevSimplified: The final DOM-related thing I want to talk about is DOM traversal. So we've talked about how to select individual elements. We've talked about how to set up events on those elements. But what happens if you want to move around the DOM, for example, I want to get the parent of an element or the children of the element. This is where DOM traversal comes in. So in our case, we can kind of think of our DOM structure as like a tree, almost like a family tree.

[00:00:19]
So here we have a div that wraps everything, which we're calling a grandparent div. Then we have another div called parent 1 and parent 2. They are children of our grandparent. And then finally we have child 1 and child 2, which are children of our parent number 1. And if we look at this in like a visual type of graph, we can see our grandparent at the top. It has 2 children, parent 1 and parent 2, and parent 1 has 2 children, child 1 and child 2.

[00:00:41]
And we can kind of think about this as like a family tree because that's kind of the terminology that JavaScript uses for traversing around different things. For example, every element has a children property and this returns an HTML collection, specifically a live HTML collection. So if we add or remove children, they'll automatically be added or removed from our array, but we can use that to get the children of an element.

[00:01:01]
So for example here, this grandparent has two children, parent 1 and parent 2. So if we select our grandparent and we get the children from it, this will give us an HTML collection with those two parents, and the length of it will be 2. We can even access individual elements from there if we wanted to. So this is how we get the direct children of a particular element. We can also get specific children.

[00:01:21]
These query selector and query selector all functions, you don't have to just use them on the document. You can use them on any HTML element you want, and it'll check all of the children and even descendants of that element. So in our case here, I have a container that I'm selecting, and I'm using query selector all directly on my container element here, which means it'll only check the code inside that container element to find the things that match this class.

[00:01:45]
So we're getting all the elements that match the item class. That is all three of these different items, which is why our length here is 3. So again, we can use query selector and query selector all on not just the document, but on any element to specifically get children or ancestors of those elements. Now we can also move around side to side to get siblings. We have the next element sibling and previous element sibling properties, and these just return to us the very next thing in line.

[00:02:12]
So here we have 1, 2, and 3 directly. They're all siblings of each other. If we first select element number 2, I can use next element sibling, that'll return to me whatever its next sibling is, which is number 3, or previous element sibling will return to me whatever comes before, which in our case is element number 1. I don't use these methods very often, but it's important to know that they're there because sometimes in rare cases they will be useful, but usually finding children and parent are much more important than finding siblings.

[00:02:39]
Now you may also notice when you're doing some testing on your own that there's actually a method called next sibling and previous sibling, and you may be wondering, okay, now these actually sound like they're the exact same thing. What could possibly be the difference? The only difference is that next sibling and previous sibling can select things that aren't just elements. They can also select things like comments in your HTML.

[00:03:00]
They can select whitespace. So in our case, if we do a query selector to get element 2 again, normally when we used next element sibling and previous element sibling, we were able to get the elements that came before and after. But what you don't realize is that in between our divs there's actually a little bit of space. You can see that space right here. And if I use previous sibling, it'll give me that space right there, which is not normally what you want, which is why I always recommend using the element version of functions rather than the non-element version because the non-element version will give you these weird spaces.

[00:03:31]
So for example, next element or next sibling and previous sibling will give you the space that comes between these two different divs, which again is usually not what you actually want. Now the more important thing is being able to traverse up and down our tree. We've already talked about moving down with children, so now we talk about moving up with parent element. Parent element will just give you whatever the parent of the current element is.

[00:03:53]
For example, if I do a document query selector to get child one, that child is right here, the parent of that child is parent number one. So when I call parent element on that child, that'll give me parent one as we can see it's logging out that parent. I can also chain this together multiple times, so I can get the parent of child one, which is our parent, and I can get the parent element of that, which is our grandparent, which is what we've done right here, child one.parentElement.parentElement, that'll give me two levels up, which will give me that grandparent element.

[00:04:23]
And again, just like the previous element sibling and previous sibling, we have this parent node function which is kind of the same thing. It can select things that aren't necessarily elements, so I'd recommend not using parent node and just using parent element instead. Again, it's kind of a quirk of JavaScript always having two different ways to do things. I would just recommend if there's an element version of the function, stick with that one because it's going to be the better one.

[00:04:46]
Now also you can find any level of ancestor, so parent only goes up one level. It just gives you the direct parent. But what if you want to check what is any ancestor in my chain that matches a specific selector? Similar to query selector, we can check downward. We can use the closest method to check upward in the exact same way. So here I've selected my delete button by this ID, so we have our delete button element, and I want to get a card that is a parent of that element.

[00:05:12]
Well I can say deleteButton.closest and pass in a CSS selector, so any element that has a class of card, and that'll give me the closest parent that has that card class, which in our case is the very direct parent. Now I can also get a section based on that section class, and you can see that gives me two levels up, essentially the closest parent element that has that class of section or ancestor in this case, and I can even go all the way to get the container element, which is all the way up here.

[00:05:36]
It'll just continually check up and up and up until there's no more elements to check and if it doesn't find anything, it'll just return null to us for non-existent. Now I would recommend whenever you're writing your code, if you're torn between if you want to use parent element or closest or if you want to use children or query selector, I would always recommend using closest and query selector because they're much more flexible in your code.

[00:06:01]
A quick example of what that may look like is we have this simple div right here for a post. This post has a title. It has some content, and it has an edit button. And inside of our JavaScript code we're getting the edit button. When we click on it, we want to do something with our code. So first we're getting the parent element, which we know is our post, and then we're getting the very first child of our post, which we know is our title, and we're logging out that title.

[00:06:22]
Obviously you can imagine we change our title or do something else inside of here. The problem with this code, while it does work right now, is what happens if we change our HTML. I've now wrapped my button inside of a div called Actions just because, you know, someone needed to change my HTML to make some CSS styles work. Well, this original code that I wrote up here no longer works because the parent of my edit button is now this div right here.

[00:06:46]
It's not actually my post. So that's why I recommend using closest and query selector because these are flexible. If I use the closest method and pass in the class of post, it doesn't matter where my button is, as long as somewhere there's a parent of it of the class post, it'll find that. Same thing here, this query selector post title, I know that as long as there's a post title somewhere inside my post, it'll find that element for me.

[00:07:09]
So it doesn't matter if your HTML changes around or certain things change in your page, as long as that overall general structure stays the same, these closest and query selector methods will continue to work while things like parent element and children will break because they're much more fragile in how their implementation works.

Learn Straight from the Experts Who Shape the Modern Web

  • 250+
    In-depth Courses
  • Industry Leading Experts
  • 24
    Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now