Reputation: 41823
This is a really basic question but...
I have some code like this
var arr = Array('blah.jpg','ha.jpg');
for (var i=0; i<array.length; i++)
{
$('div#blah' + i).click(function() {
$('img').attr('src', arr[i]); });
}
This should bind the div with id="blah0"
to change all images to 'blah.jpg'
when clicked.
Similarly, clicking the div with id ="blah1"
should change all images to 'ha.jpg'
.
However, the anonymous function won't work because it will use the value of 'i' at the time of execution, i.e. 2. This means that clicking either div will try and set all images to arr[2] - a non-existent element (interestingly not throwing a JS error on my machine but that's another story...).
How can I get the anonymous function to be created using the value of 'i' at declaration time?
As a simpler example:
for (var i=0; i<10; i++)
{
$('div#blah'+i).click(function() {
alert(i)); });
}
This should display '0' when I click 'blah0', '1' when I click 'blah1' etc.
However, by default it will display '10' no matter which 'blah' i click.
Upvotes: 3
Views: 286
Reputation: 38860
In this particular case you should be using a closure:
for (var i=0; i<10; i++)
{
(function(j){
$('div#blah'+j).click(function() { alert(j)); });
})(i);
}
(function(){ /* code */ })()
denotes a self executing function, which implies that it will use and evaluate the value of i immediately in the loop as opposed to at click time.
Upvotes: 4
Reputation: 102725
Declare a new variable inside a function that creates a new click handler that gets the current value of i as a parameter:
function makeClickHandler(arr, local_i) {
return function() {
$('img').attr('src', arr[local_i]);
};
}
var arr = Array('blah.jpg','ha.jpg');
for (var i=0; i<array.length; i++)
{
$('div#blah' + i).click(makeClickHandler(arr, i));
}
Each instance of the function gets its own copy of local_i, that doesn't change each time.
Upvotes: 5
Reputation: 41823
I have this answer so far but bit of a hack:
var arr = Array('blah.jpg','ha.jpg');
for (var i=0; i<array.length; i++)
{
eval("$('div#blah' + i).click(function() { $('img').attr('src', arr[" + i + "]); })");
}
Also:
for (var i=0; i<10; i++)
{
eval("$('div#blah'+i).click(function() { alert(" + i + ")); });");
}
Upvotes: 0
Reputation: 33474
Have 1 more variable inside the loop and increment it after using it in the closure.
var j = 0;
for (var i=0; i<array.length; i++)
{
$('div#blah' + j).click(function() {
$('img').attr('src', arr[i]); });
j++;
}
Upvotes: 0