Steven
Steven

Reputation: 131

JavaScript for loop innerHTML returning as undefined

I have been racking my brain all morning about this. In my HTML code I have a list containing letters a - j and want to console log the letter when it is clicked.

I have created a for loop to run through the nodelist and I can get the script to console log out the number of the element that is being clicked but as soon as I try and get the innerHTML or anything like that it returns undefined.

But when I just type el[3].innerHTML for example into the console it returns the letter I want.

Please help me understand why just because it's going through a for loop does it make it undefined?

I'm not just looking for the solution but also to learn why it's happening so I can become a better coder.

Thanks!

Code:

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

for(var i = 0; i < el.length; i++ ) {
  el[i].addEventListener('click', function(f) {
    return function(event) {
      event.preventDefault();
      console.log(f.innerHTML);
    }
  }(i));
}

Upvotes: 3

Views: 1152

Answers (4)

Roman
Roman

Reputation: 5210

Your Main Problem

As alredy mentiont in the comments by @teemu your f is the event object. And to access innerHtml you need to access target befor.

Idea

Currently you have n <li> elements an eventListener. You can have only one on your <ul> to have a cleaner code base.

Code

When you add the eventListener to <ul> you can access each clicked element in it via event.target.

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

list.addEventListener('click', logInnerHtml)

function logInnerHtml(event) {
    event.preventDefault()
    console.log(
        event.currentTarget.innerHtml
    )
}

Example

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

list.addEventListener('click', logInnerHtml)

function logInnerHtml(event) {
  console.log(event.target.innerHTML)
}
<ul>
  <li>first</li>
  <li>second</li>
</ul>

Upvotes: 0

Santosh Sapkota
Santosh Sapkota

Reputation: 140

Here is working example, I think it was problem with passing correct element

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

   for(var i = 0; i < el.length; i++ ) {
   el[i].addEventListener("click",function(e){

     return function(event){
      event.preventDefault();
      console.log(e.innerHTML);
   };
 }(el[i]));
}

Upvotes: 0

freginold
freginold

Reputation: 3956

When you pass i as your argument into the function, f takes on the value of i so when you try to get f.innerHTML you're attempting to get the HTML from an integer, rather than from the element that was clicked.

You can use this to target the element that was clicked. Here is a working example:

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

  for(var i = 0; i < el.length; i++ ) {
  el[i].addEventListener("click",function(f){

    return function(event){
        event.preventDefault();
        console.log(this.innerHTML);
    };
  }(i));
}
<ul>List
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
</ul>

Edited with corrected information thanks to @Teemu.

Upvotes: 1

Nikola Lukic
Nikola Lukic

Reputation: 4244

You miss name of variable at :

console.log(this.innerHTML);

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

console.log(el)

  for(var i = 0; i < el.length; i++ ) {
  el[i].addEventListener("click",function(f){

    return function(event){
        event.preventDefault();
        console.log(this.innerHTML);
    };
  }(i));
}
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>

Upvotes: 1

Related Questions