I have a some buttons, which are stored in an array. I then loop through that array to add a click event to each button. Each click alerts the value of i
. I expect the values to be 1
, 2
, 3
and so on, but they always come back as one value, in case 3
.
Can you explain why this happens and how to fix it?
Please see this a jsFiddle. Code below:
var theButtons = ['.button.one', '.button.two', '.button.three'];
for (i=0; i<theButtons.length; i++) {
$(theButtons[i]).click(function () {
alert(i); // always returns 3
});
}
Please explain it as simply and clearly as you can - I'm somewhat of a beginner at Javascript and programming.
You have some sort of for/next loop that then calls some asynchronous function. When the function runs, what you see when the code runs is that the last value of the loop index is the value that gets used in the function for every instance that it gets called.
Comparison of performance of loops available in JavaScript : In case of multiple iterations of the loop, and where the size of array is too large, for loop is the preference as the fastest method of elements' iteration.
A JavaScript for loop executes a block of code as long as a specified condition is true. JavaScript for loops take three arguments: initialization, condition, and increment. The condition expression is evaluated on every loop. A loop continues to run if the expression returns true.
By the time you click on the button i === 3
. Need to pass the value of i
into a closure:
for (var i = 0; i<theButtons.length; i++) { // do `var i` so the i is not global
(function(index){
$(theButtons[i]).on('click', function () {
alert(index); // index === the value that was passed
});
})(i); // pass the value of i
}
Fiddle Demo: http://jsfiddle.net/maniator/fE55Y/3/
Just use EACH method:
$( ".button" ).each(function( index ) {
$(this).click( function(e){
alert( index + ": " + $(this).text());
});
});
Fiddle: http://jsfiddle.net/fE55Y/4/
Agreed that .each()
is not needed for what's been asked. Here's the one without using .each()
method.
$(".button").click(function () {
alert("Button Index: " + $(this).index());
});
Welcome to asynchronous programming and global variables!
The problem you are seeing here is because of the fact that i
is declared globally in this case, in that is accessible from anywhere by anything.
So, what happens when your script is executed is:
The problem here is that the function you provided is executed outside of your loop (e.g. when the click happens), so the value of i
is whatever it was in the last iteration, in this case 2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With