Addeventlistener Using For Loop Gives Me An Undefined Result
Solution 1:
This is because, i is a variable defined outside your event handler function, which is incremented by each iteration. So when you finish the iterations of the for loop, the value of i is equal tolen, which causes li[i] to be undefined. And if you ask me why it's value is not considered during the iteration, it's because your event handler function is only executed when the event occurs (not when you are setting the event handlers by for loop). So you can make a variable inside the function scope which won't be changed by iteration. Better use this from inside the event handler to get the same thing.
for(var i=0,len=li.length; i<len; i++){
li[i].addEventListener('click',function(e){
e.preventDefault();
alert(this);
vardata = this.dataset.info;
showDiv.innerHTML = data;
},false);
}
Understanding the for loop
Why the value of i is equal to len after for loop is finished? Let's have a simpler example to make you understand the situation.
varlen = 2;
for(var i=0; i<len; i++; {
//Do anything here
}
console.log("after for loop: i = " + i);
Lets's go through the iterations.
i = 0, matches the conditioni<len, which proceeds with executing the code block and executesi++after that, which makesi=1;i = 1now, matches the conditioni<len, which proceeds with executing the code block and executesi++after that, which makesi=2;i = 2now, fails to match the conditioni<lenand stops the iteration.
So, you have set the i=2 before you go to step 3. So your final console.log after for loop will say, after for loop: i = 2
Solution 2:
This occurs because of scope. Inside the EventListener, you have an anonymous function, because of this, you are no longer in the scope of li. However, you can refer to it with the this keyword. See the alert that I've replaced in your code.
(function(){
var innerDiv = document.getElementsByClassName('showDiv')[0];
//var li = document.querySelectorAll('ul.idiv li'); var li = document.getElementsByTagName('li');
for(var i=0,len=li.length; i<len; i++){
li[i].addEventListener('click',function(e){ // you are now inside a different function block here.
e.preventDefault();
alert(this.innerHTML);
var data = li[i].dataset.info;
showDiv.innerHTML = data;
},false);
}
}()); <divclass="showDiv">Show data: </div><divclass="outerDiv"><ulclass="idiv"><lidata-info="datashow"><ahref="">111</a></li><lidata-info="dataHide"><ahref="">222</a></li><lidata-info="dataToggle"><ahref="">333</a></li></ul></div>Solution 3:
Another approach in addition to the answers of other posters is to use a local scope with function. In JavaScript function is the most reliable way of creating a new scope. Taking the above example,
for (var i = 0; i < li.length; i++) {
(function(i) {
var j = i;
li[j].addEventListener('click', function(e) {
e.preventDefault();
var data = li[j].dataset.info;
showDiv.innerHTML = data;
}, false);
})(i);
}
I have created a new scope that that will isolate the value of variable i. If you're using ES6 you can use let keyword to do just the same thing. All you have to do is replace var with let. You can also use let in a for loop that will give you a whole new scope that is local to for loop.
Solution 4:
You need to refer to the particular li on which you want to attach the event
(function(){
var innerDiv = document.getElementsByClassName('showDiv')[0];
var li = document.getElementsByTagName('li');
for(var i=0,len=li.length;i<len;i++){
var thisLi = li[i];
thisLi.addEventListener('click',function(e){
e.preventDefault();
alert(thisLi.innerHTML);
var data = thisLi.getAttribute('data-info');
innerDiv.innerHTML = data;
},false);
}
}());
When click will be executed i will have value as 3 (in your case) so li[i]will be different. You can check the console of THIS to check value of i on click event
Post a Comment for "Addeventlistener Using For Loop Gives Me An Undefined Result"