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

There was an error with your code: ReferenceError: Strict mode forbids implicit creation of global property 'listPara'

I can't see why I'm getting this error. Also, I don't understand how my function isn't automatically finding the paragraph immediately in front of any button.

I'm really lost here. I don't think the instructor did a good job explaining this.

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

list.addEventListener('click', function(e) {
  if (e.target.tagName == 'BUTTON') {

    let button = document.querySelector('button');
    listPara = button.previousElementSibling; 
    listPara.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>

1 Answer

Cameron Childres
Cameron Childres
11,820 Points

Hey Roberto~

I'm no expert here but I'll see if I can help out.

First off, strict mode is used in the challenges here and it gets angry when you don't initially declare a variable with var, let, or const. It's a way to force you in to writing better code. I get away with initializing for loops with i=0 instead of let i=0 when I'm working locally which has gotten me in trouble a few times -- strict mode doesn't let me do that. For a more plain-English explanation you can check out this GeeksforGeeks post.

On to what's happening in your code:

On line 2 you define button with getElementsByTagName, giving an array with all of the button elements. You then redefine this in your if statement with querySelector, which returns only the first button in the document it encounters. What you're saying here is "when any button in the list is clicked, look for the first button, add the class 'highlight' to the element before it" -- and that's exactly what it does. You can test this in the challenge by adding let before listPara or by trying it an environment without strict mode enabled.

Thing is, you don't actually need to define anything new at all. The if statement provided in the challenge is already checking that the event target is a button. You want to apply the class to the element before the button that is clicked (the event target), so why not work with this directly?

Here's my solution:

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

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

This says, "In the targeted list listen for click events. If the click is on a button element, apply the class 'highlight' to the element sibling that comes before the button that was clicked."

I hope this helps! Let me know if there's any confusion.