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) Getting a Handle on the DOM Selecting Elements with the Same Class Name

Stephen Gough Jr
Stephen Gough Jr
4,187 Points

Adding EventListener to this video's code

I tried experimenting by making the purple words change to the color purple after clicking on them, but it doesn't work for me and I'm wondering why. My code is:

const myList = document.getElementsByTagName("li");

myList.addEventListener("click", for (let i = 0; i < myList.length; i += 1) { myList[i].style.color = "purple"; })

const errorNotPurple = document.getElementsByClassName("error-not-purple");

for (let i = 0; i < errorNotPurple.length; i += 1) { errorNotPurple[i].style.color = "red"; }

I tried following the example of the first video in this Javascript and DOM course, but no luck.

1 Answer

Collin Halliday
seal-mask
.a{fill-rule:evenodd;}techdegree
Collin Halliday
Full Stack JavaScript Techdegree Student 17,491 Points

Hi Stephen,

There are a couple of issues with your code. First, you are trying to add an event listener to an HTML Collection. That is not going to work. When you grab all of the list items and store them in the variable myList, that variable represents a collection of HTML elements, and you cannot add an event listener directly to that collection. If you wish for items in that collection to have event listeners, you can either (1) add an event listener or listeners to some or each of the element by looping over the collection, or (2) you can add one event listener to the parent element of these elements that, through event bubbling, listens for click events on some or all of its children, and modifies their properties according to the code you write. The latter is often the more efficient and more DRY approach.

For instance, if you wanted to add event listeners to each of the list items that include purple items, you could loop through myList and add event listeners to those list items that do not contain the class "error-not-purple."

for(let i = 0; i < myList.length; i++) { if(myList[i].className !== "error-not-purple") { myList[i].addEventListener("click", function(event) { event.target.style.color = "purple"; }); } }

In this loop, I am looping over each list item in the myList collection, and where the item does not have the class "error-not-purple", I am adding an event listener for click events. Each event handler includes a callback function that takes the event as an argument and manipulates elements through use of the target property on that event argument. This allows you to access the target of each click event and change the value of its color property to 'purple'. Because only list items that do not contain the class 'error-not-purple' have the above event listener, the non-purple list items will not respond to mouse clicks.

Alternatively, you could add one event listener to the unordered list element that is the parent of the list items in the myList collection, and you could create the same functionality through use of event bubbling. This is the basic concept that the click event, and most others, will bubble up from the element where an event occurs through that element's ancestor elements. You can find more information on this concept at the following website: https://javascript.info/bubbling-and-capturing

document.getElementsByTagName('ul')[0].addEventListener('click', function(event) { if(event.target.className !== 'error-not-purple') { event.target.style.color = 'purple'; } });

In this code snippet, I am first targeting the ul element, then attaching an event listener to it. The associated event handler includes a callback function that, like the callback function in the example above, takes the click event as an argument, and makes use of the target property of the click event to manipulate the value of the color property on only those list items that do not contain the class 'error-not-purple.'

Another issue with your code above is your attempt to include a for loop as the second argument of your call to "myList.addEventListener". You can use a for loop in situations like this, but you will want to include the for loop inside of a callback function.

I hope that was somewhat helpful. Best of luck!

Stephen Gough Jr
Stephen Gough Jr
4,187 Points

I admit, some of that went over my head because I'm still very...foggy with functions, but after rereading your comment a few times, I think I understand most of what you are talking about. I will add your examples to the code and try to gather a clearer understanding. I deeply appreciate your help, though, as I do feel better about my EventListener dilemma.