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

Quinton Shuman
Quinton Shuman
7,068 Points

Bummer: There was an error with your code: TypeError: 'undefined' is not an object (evaluating 'prevP.className')

I've been stuck on this for hours and I'm begging for some help to answer what is wrong with my code. Please, please, please help.

The task: 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.

My answer:

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

list.addEventListener('click', function(e) {
  if (e.target.tagName == 'BUTTON') {
    var prevP = e.previousElementSibling;
    prevP.className += "highlight";
  }
});

Mod edit: added code markdown for readability. Check out the "markdown cheatsheet" link below the comment box for tips on formatting.

2 Answers

Cameron Childres
Cameron Childres
11,818 Points

Hi Quinton~

Your variable prevP is trying to look for a previous element sibling for the event object. The event object contains a LOT of information. To access the target of your event you need to use the event's target property. This will return the element that is clicked, allowing you to then use previousElementSibling.

Rewriting your variable with the target property would look like:

var prevP = e.target.previousElementSibling;
Quinton Shuman
Quinton Shuman
7,068 Points

I guess I will have to go back and look more into the event object. I thought that if it was in the event listener it would already target that specific event. Does the target property simply exist to confirm that you do in fact want to select that specific event?

Quinton Shuman
Quinton Shuman
7,068 Points

Also thank you so much for helping me lol. Should have been the first thing I mentioned. I do really appreciate it.

Cameron Childres
Cameron Childres
11,818 Points

The target property lets us be specific about selecting the element that was clicked.

In this exercise the event listener is added to the <ul> element so that we can take advantage of propagation and not have to add a listener to every single <button>. When something in the <ul> is clicked it's the <ul> that fires the event, generating an event object with loads of information including what element was clicked (e.target) and what element fired the event (e.currentTarget).

Without these properties the browser couldn't know what element we intended to act on. Should it go with the <ul> or the <button>? Since we want to act on the clicked element we use e.target. If we instead wanted to act on the <ul> that fired the event we would use e.currentTarget.

PS -- using the additional assignment operator to add the class means that every time you click the button you're concatenating 'highlight' on to the classes already present. If you click the button 3 times you'll get this:

<p class=​"highlighthighlight">​Events​</p>​

It would be more appropriate for this specific exercise to get rid of the plus sign and just use the assignment operator '='.

Quinton Shuman
Quinton Shuman
7,068 Points

interesting that it would concatenate it instead of just adding additional classes thanks for the tip