JavaScript JavaScript and the DOM Traversing the DOM Sibling Traversal

Nicholas Dunn
Nicholas Dunn
7,928 Points

Struggling with this concept

Hey team,

I'm having difficulty working out how to correctly target the P tag within the previous list item.

I'm hoping someone can have a look at my code and see where I've gone wrong.

Or point me in the right direction as to what I should be reading up on. I've rewatched the videos a few times but I'm just struggling.

TIA.

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


list.addEventListener('click', function(e) {
  if (e.target.tagName == 'BUTTON') {
    let li = e.target.parentNode;
    let prevLi = li.previousElementSibling;
    let ul = li.parentNode;
    let p = prevLi.querySelector('p');
    p.className = "highlight";


  }
});
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>

5 Answers

Nicholas Dunn
Nicholas Dunn
7,928 Points

Really not getting it haha

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

list.addEventListener('click', function(e) { if (e.target.tagName == 'BUTTON') { let p = document.querySelector('p').previousElementSibling; p.className = 'highlight'; } });

This is what I've got and it says one or more buttons isn't affecting it's sibling

ARGGH

Jonathan Grieve
Jonathan Grieve
Treehouse Moderator 82,446 Points

Fair enough. I'll give you the answer and explain it. :)

First, I'm declaring a variable called p (it could be anything and probably should be something more meaningful) but p is going to hold event.target, which as you can see from the if statement is going to be a button element. The previous sibling of that is a paragraph element, which is what we want. So all we need to do is assign that to the p variable.

let p = e.target.previousElementSibling

Next, we already have a reference to the p variable. So we can simply do

p.className = "hightlight";

There's no need to start from the parentNode. I know it;s confusing and overwhelming at times. I experience that feeling a lot. :)

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


list.addEventListener('click', function(e) {
  if (e.target.tagName == 'BUTTON') {
    let p = e.target.previousElementSibling;
    p.className = "highlight";
  }
});
Jonathan Grieve
MOD
Jonathan Grieve
Treehouse Moderator 82,446 Points

What you need to target is the paragraph element that is the immediate sibling of a button element. The paragraph element is the thing you need to add the class to.

You can do this by declaring a p variable and adding the previousElementSibling method to e.target. Then use the className method on P.

Nicholas Dunn
Nicholas Dunn
7,928 Points

Thanks for responding Johnathan. To be honest that's what I was trying to do, could you perhaps show me what the code should look like?

I declared the P variable inside the function and thought I was selecting the value.

If I'm reading the challenge correctly it's selecting the P tag in the Li item above the current li tag. Not the P tag within the current li tag.

Can't see where I've gone wrong tbh

Jonathan Grieve
Jonathan Grieve
Treehouse Moderator 82,446 Points

I wanted to avoid giving you the answer in straight code but I'll meet you half way :)

You only need a couple of lines of code in your event handler and you don't need to worry about traversing from the parent element.

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


list.addEventListener('click', function(e) {
  if (e.target.tagName == 'BUTTON') {
    //line of code to declare a variable for your paragraph and assign it to the traversal from the button to the paragraph element
   //line of code to select the p variable and change the class to highlight
  }
});

I hope this helps :)

Nicholas Dunn
Nicholas Dunn
7,928 Points
var list = document.getElementsByTagName('ul')[0];

list.addEventListener('click', function(e) { if (e.target.tagName == 'BUTTON') { let p = document.querySelector('p').previousElementSibling; p.className = 'highlight'; } });
Nicholas Dunn
Nicholas Dunn
7,928 Points

Ahhh I was missing the .target method for E. When I was trying to target E it was saying undefined variable.

Thank you so much for your patience in explaining it to me!