Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

JavaScript JavaScript and the DOM (Retiring) Responding to User Interaction Event Delegation

Why does this not work?

Hi Guys,

Why does this solution not simply work?

I understand that it may not pass the challenge, as the challenge is asking for a conditional, i.e. a specific solution. But would it be sufficient code?

Thanks

app.js
let section = document.getElementsByTagName('input');

section.addEventListener('click', (e) => {
  e.target.style.backgroundColor = 'rgb(255, 255, 0)';
});
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>JavaScript is an exciting language that you can use to power web servers, create desktop programs, and even control robots. But JavaScript got its start in the browser way back in 1995.</p>
            <hr>
            <p>Things to Learn</p>
            <ul>
                <li>Item One: <input type="text"></li>
                <li>Item Two: <input type="text"></li>
                <li>Item Three: <input type="text"></li>
                <li>Item Four: <input type="text"></li>
            </ul>
            <button>Save</button>
        </section>
        <script src="app.js"></script>
    </body>
</html>

4 Answers

Hi Brandon,

Thanks once again. I'm pleased to say that just before your answer I had managed to find my way to it.

I got the sense that the e was needed rather than event, even though your explaination has hammered home why.

I also thought there may be an isue with the syntax of the conditional, so I tried alerting the cilcked element so see what it presented itself as, and saw it was all caps. I tried that and it worked!

Also duly noted on the == / === issue.

Thanks again! This is a great feeling!

Brandon White
seal-mask
MOD
.a{fill-rule:evenodd;}techdegree seal-36
Brandon White
Treehouse Moderator

Hi Luke,

The reason your code would not work as written is because document.getElementsByTagName doesn’t return a single element/node. It returns a list of elements. Even if there’s only one element on the page that fits the string passed into the method, it still returns that element in list form.

So when you then try to call addEventListener on that list of elements, Javascript doesn’t know how to do that.

[<p1>, <p2>, <p3>].addEventListener()

The above statement wouldn’t make sense to the Javascript interpreter (which is kind of what happens to the second statement when you change the code in the first statement from (‘section’)[0] to (‘input’)).

The [0] after the parens says return just the item in the list at index 0.

Now you could for...loop the section variable, and add the event listener to each iteration of the list item within the for loop. But if you want to have the event listener added to the entire section element, then it would be easier and more efficient to test for the target of the click inside the listener, and then change the background color of the targeted element, but only if the targeted element is an input element.

Does that make sense? If not let me know.

Hi,

That makes perfect sense. What a fantastic service you guys offer. Thank you for taking the time.

I had actually made a bit of headway since positing the question. Not least becasue I refreshed the page and realised there was the [0] at the end of the selector. I was trying to backwards engineer it using the existing working code, and must have deleted that bit when doing so which was the main cause of my error!

So all that you've said makes sense. I'm now trying and stuck a little further down the line, if you're able to help again (hopefully I will have solved this before you respond!):

let section = document.getElementsByTagName('section')[0];

section.addEventListener('click', (e) => {
    if(event.target.tagName == 'input') {
  e.target.style.backgroundColor = 'rgb(255, 255, 0)';
       }
});

Many thanks again for your helpful response

Brandon White
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Brandon White
Treehouse Moderator

Hi Luke,

Your code looks good, there are just two things that's causing it to not work (and one thing that I'll mention that's simply good practice).

The first thing is in your test for the if statement you're checking if event.target.tagName is equal to 'input'. The JavaScript interpreter does not know what event is though. In the definition of the callback function (i.e. (e) => {...}), the parameter that the function accepts is e. So when the event is passed into the callback as an argument, it will be stored into the variable e. So it wouldn't be event.target.tagName, it would be e.target.tagName. Hopefully that makes sense.

The second thing is in the same statement. I had to refresh my memory on this myself, but the tagName that is returned from the Element.tagName property (https://developer.mozilla.org/en-US/docs/Web/API/Element/tagName) is returned in all caps. So instead of checking if the tag name of the event's target is 'input', you'll want to check if it's 'INPUT'.

Finally (and this is not breaking your code), but the == (equality operator) attempts first to convert types and then compare them, while the === (strict equality operator) compares both values and types, which is what you'll typically want to happen. Using the == operator unless you're actively wanting the interpreter to convert types prior to comparing can have unexpected consequences (for example, '\n\r\t' == 0 returns true (because apparently a string of only whitespace is equal to zero). So just be careful when you're using the == operator.

HI Brandon.

I could have sworn I replied to this earlier, so excuse my shorter response for to your supportive input.

Long story short it makes complete sense, and I had figured this before your response. I tested it by using alert and using the capitalised response.

Duly noted on the the == / === issue.

Thanks again

Brandon White
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Brandon White
Treehouse Moderator

Haha. You did reply before. It’s the first message/answer that shows on the page for me. I appreciate you responding again though.