Reputation: 131
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
Reputation: 5210
As alredy mentiont in the comments by @teemu your f
is the event
object. And to access innerHtml
you need to access target
befor.
Currently you have n <li>
elements an eventListener
. You can have only one on your <ul>
to have a cleaner code base.
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
)
}
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
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
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
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