Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript JavaScript and the DOM (Retiring) Traversing the DOM Sibling Traversal

Tried a lot but failed .Please Help!!

app.js

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

list.addEventListener('click', function(e) {
  if (e.target.tagName == 'BUTTON') {
    let li = e.target.parentNode;
    let prevP = button.previousElementSibling;

    prevP.className = 'highlight';
     let ul = li.parentNode;
  }
});
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>
Daniel Arundel
Daniel Arundel
7,951 Points

Hey Jyoti,

It seems that you have grasped the right concepts but made things more complicated than they need be. The β€˜button’ tags are already targeted in the if statement given, so there is no need for your button variable. Secondly, the aim is to add the class to the p elements, and as far as I can tell, you have targeted the ul element with your let li variable.

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

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

So, in the above code we are saying "if the tag that we are targeting is called 'button' then we will target its previous element sibling using the variable p, in this case the previous element would be the p element. In the next line of code, we simply add the required class name to the element we targeted in the p variable.

At least, that is how I understand it. I hope this helped and that if anyone spotted any flaws in my logic they would correct me - I'm learning, too =)

Cheers

~ Dan

1 Answer

Brendan Whiting
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Brendan Whiting
Front End Web Development Techdegree Graduate 84,738 Points

I'm getting this error with your code: "TypeError: 'undefined' is not an object (evaluating 'prevP.className = 'highlight'')"

Here's what's going on: getElementsByTagName('button') returns a collection of all the button elements, not just one. So later on, when you try let prevP = button.previousElementSibling;, that method doesn't exist - it's a method on single html nodes, not on collections - so the result is assigning undefined to the variable prevP, which means when we try and access the className property of undefined we get an error.

You're on the right track. You don't actually need getElementsByTagName('button'). You already have a reference to the button element: it's e.target. We know this since we've just checked that the target element was a button. Let me know if you need more help.

const list = document.getElementsByTagName('ul')[0]; //const button = document.getElementsByTagName('button');

list.addEventListener('click', function(e) { if (e.target.tagName == 'BUTTON') { let li = e.target.parentNode; let prevP = button.previousElementSibling;

prevP.className = 'highlight'; let ul = li.parentNode; } })

STILL NOT WORKING!!! CAN YOU PROVIDE ME WITH YOUR SOLUTION?

Brendan Whiting
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Brendan Whiting
Front End Web Development Techdegree Graduate 84,738 Points

All you need it this:

    let prevP = e.target.previousElementSibling; 
    prevP.className = 'highlight';

Since we've just checked if e.target.tagName == 'BUTTON', we know that we have a reference to the button that was just clicked in e.target. We can access the <p> element next to it with previousElementSibling.

We don't need to grab all the buttons with document.getElementsByTagName('button');, and we don't need a reference to the parent node li or ul elements either.