JavaScript JavaScript and the DOM Traversing the DOM Sibling Traversal

Khumoyunmirzo Nosirov
Khumoyunmirzo Nosirov
8,345 Points

I didn't understand what challenge is asking ,

The <ul> stored in the variable list has a click event listener that targets each <button> in the list. Complete the code to add a class of highlight to a <p> element that's an immediate previous sibling of the button being clicked.

app.js
var list = document.getElementsByTagName('ul')[0];

list.addEventListener('click', function(e) {
  if (e.target.tagName == 'BUTTON') {

  }
});
index.html
<!DOCTYPE html>
<html>
    <head>
        <title>JavaScript and the DOM</title>
    </head>
    <link rel="stylesheet" href="style.css" />
    <body>
        <section>
            <h1>Making a Webpage Interactive</h1>
            <p>Things to Learn</p>
            <ul>
                <li><p>Element Selection</p><button>Highlight</button></li>
                <li><p>Events</p><button>Highlight</button></li>
                <li><p>Event Listening</p><button>Highlight</button></li>
                <li><p>DOM Traversal</p><button>Highlight</button></li>
            </ul>
        </section>
        <script src="app.js"></script>
    </body>
</html>

4 Answers

Antony Pesantez
Antony Pesantez
1,330 Points

Hi, Khumoyunmirzo Nosirov

As you seen in the course, Guil Hernandez mentioned the previousElementSibling property.

The code challenge asks you to add the class of "highlight" to the p element/tag. Seeing the code provided you can tell that in the conditional statement we are assigning the event target to the button element.

event target = e.target

var list = document.getElementsByTagName('ul')[0];

list.addEventListener('click', function(e) {
  if (e.target.tagName == 'BUTTON') {
  }
});

Now if you look in the index.html file you will see the button elements is stored inside the p elements. So now knowing that event target is assigned to the button element we can get a hold of the p tag by traversing to its sibling using the previousElementSibling property. It should look like this:

let p = e.target.previousElementSibling;

Now that you got that we can move on to the last & easy part.

Adding the class "highlight" to the p element.

p.className = "highlight";

Just for no confusion. When I said "assigned" i didn't mean it like a = would directly assign things. The conditional statement is doing something like it.

Julianna Kahn
Julianna Kahn
20,699 Points

I'm learning a lot, thank you.

Julianna Kahn
Julianna Kahn
20,699 Points

1) Can you please help explain the logic between the 2 syntax issues below? list.addEventListener('click', function(e) { and code I seen so often: list.addEventListener('click', () => {

2) And what is the significance of including the array name in the following statement? var list = document.getElementsByTagName('ul')[0];

Antony Pesantez
Antony Pesantez
1,330 Points

Sure.

  1. So from my understanding I believe there's no difference in terms on functionality, but version wise there is. Arrow functions were introduced in ES6, and functions have been imported for a while.

  2. When you write a number inside brackets ( [0], [1], [2], etc ), in means you're looking for a specific element.

For e.g.,

<div> </div>
<div> </div>

Instead of grabbing one of these elements with an ID or Class, you can use getElementsByTagName. For instance to grab the second div you can do

document.getElementsByTagName('div')[1];

or if you want the first div

document.getElementsByTagName('div')[0];
Julianna Kahn
Julianna Kahn
20,699 Points

Your explanation about the syntax of .addEventListener makes things a lot clearer, thanks.

But if you can just clarify a little more about using the array [0]. I understand the array syntax but I'm still not sure why it's needed here, since the html code only contains one ul element.

Antony Pesantez
Antony Pesantez
1,330 Points

No problem.

If you were to use getElementsByTagName like this:

var list = document.getElementsByTagName('ul')

You would get back a HTMLCollection. Even if there's only 1 ul element it's still going to return a collection. Here's a live example of what it would look like in your console.

alt text

So you can still use getElementsByTagName the way I showed you above. The only problem is that you would still have to get access to the html element using an array with a number inside.

list[0];

Alternatives for this would be to use querySelector, and you wouldn't need to use the array to specify the first element because it automatically does that for you. But you would need it if you wanted to target the/a second element.