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 trialjyoti barman
Courses Plus Student 1,280 PointsTried a lot but failed .Please Help!!
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;
}
});
<!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>
1 Answer
Brendan Whiting
Front End Web Development Techdegree Graduate 84,738 PointsI'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.
jyoti barman
Courses Plus Student 1,280 Pointsconst 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
Front End Web Development Techdegree Graduate 84,738 PointsAll 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.
Piotr Manczak
Front End Web Development Techdegree Graduate 29,363 PointsYour comment helped me greatly. Thanks, you are my hero.
Daniel Arundel
7,951 PointsDaniel Arundel
7,951 PointsHey 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.
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