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) Responding to User Interaction Listening for Events with addEventListener()

Brian Patrick
PLUS
Brian Patrick
Courses Plus Student 2,770 Points

Uncaught TypeError: Cannot read property 'textContent' of undefined

for(var i = 0; i < listItems.length; i++){

  listItems[i].addEventListener('mouseover', () =>{
    listItems[i].textContent = listItems[i].textContent.toUpperCase();                             
  });

  listItems[i].addEventListener('mouseout', () => {
    listItems[i].textContent = listItems[i].textContent.toLowerCase();                            
  });

};

It works outside of a loop but not inside the loop. Why?

5 Answers

Dave StSomeWhere
Dave StSomeWhere
19,870 Points

Pretty sure it is a JavaScript closure/scoping issue - your index i is resolved to the value at the end of the loop when it tries set the eventlistener and textContent.

Try "let" instead of "var" (works for me with let).

MDN let

Steven Parker
Steven Parker
231,236 Points

The value of "i" is not the same when the event happens as when the handler is attached. Dave has the right idea and you can correct this by using "let" instead of "var" to constrain the scope and give each handler its own value for "i".

Use let instead, and try to refactor your function for a better experience:

const listItems = document.getElementsByTagName('li');

for(let i = 0; i < listItems.length; i += 1) {
 let liItem = listItems[i];
liItem.addEventListener('mouseover',() => {
   liItem.textContent = liItem.textContent.toUpperCase();
 });

liItem.addEventListener('mouseout',() => {
   liItem.textContent = liItem.textContent.toLowerCase();
 });
}  ```
Jaspal Singh
Jaspal Singh
13,525 Points

Hi Brian

I think it is not recognizing the dom element on which your applying the textContent property. So pls check that you have properly selected or referenced the listItems with the help of getElementsByTagName.

@Dave varmutant was right!

Just use LET instead of VAR and you should be fine.