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 trialGreg Schudel
4,090 PointsBummer! One or more of the buttons do not affect their sibling paragraphs.
Not sure how to figure this one out. I am not clear on what they are asking. Do they want you to put a class on the previous paragraph element. Why would you need to put a parentNode property on this problem?
What am I doing wrong here?
app.js
const list = document.getElementsByTagName('ul')[0];
list.addEventListener('click', function(e) {
if (e.target.tagName == 'BUTTON') {
let button = event.target.parentNode;
let buttonParent = button.parentNode;
if (buttonParent) {
buttonParent.querySelectorAll('p').className = "highlight";
}
}
});
<!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>
6 Answers
Steven Parker
231,271 PointsYou're quite right, you do not need to use the parentNode property. Since the "if" condition has already determined that e.target is the button, you only need to use the previousElementSibling property to access the paragraph.
So the whole thing can be done in one line.
Zack Lee
Courses Plus Student 17,662 Pointsto add what was said, I found a syntax error in your eventListener 'if' statement. you wrote event.target, but passed the event as the variable 'e.' Use "e.target.parentNode" to keep it consistent.
Steven Parker
231,271 PointsGood point, and it' s easy to do accidentally — I think I've even seen this in one of the instructional videos. But the global "event" variable shouldn't be relied on, particularly when the object was passed in and available that way. You could also use it as "this".
But in this case, all that code will be going away. Right, Greg?
Greg Schudel
4,090 PointsBut in this case, all that code will be going away. Right, Greg?
how can you do of this in one line of code? I've watched the video and taken Quizzes and there are at least three things you need to do to traverse the DOM as being asked here.
1.) Select the selection
2.) Use the parentNode
property of that selection
3.) use the nextElementSibling
property along with className
to apply the class, right?
This is what I have now... at this point I give up. I'm moving onto something else until I hear back from someone.
const list = document.getElementsByTagName('ul')[0];// why are we selecting the first in the index? Why do we even need this '[0]' ?
list.addEventListener('click', function(e) {
if (e.target.tagName == 'BUTTON') {// why are we using the e.target object again?
e.target.nextElementSibling.className = 'highlight';
}
});
Zack Lee
Courses Plus Student 17,662 PointsYou can't use nextElementSibling because <button> is the last child of your <li> tag.
Try using previousElementSibling. Also, if the challange is asking you to use a specific syntax then even if you use more efficient code the challenge may still fail.
Zack Lee
Courses Plus Student 17,662 PointsAlso, to clarify, the "e.target" is used to select the element from which the event derived.
Steven Parker
231,271 PointsIt looks like you've almost got that one-liner solution (no "parentNode" needed)!
But the paragraph comes before the button, so the property you want is the previousElementSibling.
Greg Schudel
4,090 PointsThis is what I did, FINALLY GOT IT!!!! THANK GOD!!
Couple questions...
const list = document.getElementsByTagName('ul')[0];
list.addEventListener('click', function(e) {
if (e.target.tagName == 'BUTTON') {
e.target.previousElementSibling.className = 'highlight';// why do I have to rewrite e.target here in order to call it correctly?
}
});
Also, to clarify, the "e.target" is used to select the element from which the event derived.
Why can't I just use parentNode
property to do that? Does anybody have any other solutions that I could use to do the same thing (even if it causes errors in Treehouse Editor)?
Steven Parker
231,271 PointsBut what element would you get the parentNode
property from? Using "e.target" gives you a starting point that you can traverse from.
Your code doesn't rewrite "e.target", it just uses it as a reference to get to the paragraph element that comes before the button. Then you're only changing the className
property on that element.
And any working solution would pass the challenge. This just happens to be a particularly concise and efficient one.
Glad to see you solved it! Happy coding!
Greg Schudel
4,090 PointsAnother question for this code. Was taking this challenge again and noticed some other questions.
const list = document.getElementsByTagName('ul')[0];
list.addEventListener('click', function(e) {
if (e.target.tagName == 'BUTTON') {
e.target.previousElementSibling.className = 'highlight';
/* why do I have to rewrite e.target here in order to call it correctly? Should this work just fine?
previousElementSibling.className = 'highlight';
*/
}
});
Zack Lee
Courses Plus Student 17,662 PointsNo, previousElementSibling needs to be in reference to something. Try that snipet, you'll get an error. e.target specifies where the program should start looking in the DOM
Steven Parker
231,271 PointsThe name "previousElementSibling" is an element property. By itself it is an undefined reference and causes an error.
Greg Schudel
4,090 PointsThe name "previousElementSibling" is an element property. By itself it is an undefined reference and causes an error.
So, even within functions that have conditions on them, when I'm trying to manipulate the DOM, I ALWAYS have to specify where to look in the DOM? OR is that too general a question to ask for something this specific?
Steven Parker
231,271 PointsI think it's fair to say in general you will always need a DOM component to start with in order to make use of traversal properties or methods.
And a condition of an "if" statement doesn't have any effect on the code in the associated code block other than to determine if it will be executed at all.
Jaspal Singh
13,525 PointsJaspal Singh
13,525 PointsHi Greg
first of all use addEventListener on the parent of button that is ul and than use the prevoiuselementsibling on the button which is P element and than change the class of p element.
thanks