Reputation: 31249
I have a little problem: slideHelpers.total = 4
for (i=1;i <= slideHelpers.total; i++) {
$('<a href="#">' + i + '</a>').bind('click', function(){ alert('go to the ' + i + ' slide')}).appendTo('.slideaccess')
}
the alert gives out 5 what is logic, because when the function click triggers i is actually 5. But i would like to have the same i as in my <a>
tag. What is the best way to handle this?
I could put i in the data() of the <a>
tag for example but i am sure there is a easier way.
Upvotes: 0
Views: 133
Reputation: 111890
for (i=1;i <= slideHelpers.total; i++) {
$('<a href="#">' + i + '</a>').bind('click',
(function(i){
// Capture i in closure
return function(){
alert('go to the ' + i + ' slide')
};
})(i)
).appendTo('.slideaccess')
}
Optimised:
var ary = [], i = 0, n = slideHelpers.total,
open = '<a class="index" href="#">',
close = '</a>';
// Fill array with numbers: 1,2,3,4,5...
while (++i < n) ary[i] = i + 1;
$('.slideaccess').append(
open + ary.join(close + open) + close
).delegate('a.index', 'click', function() {
var index = $.text(this);
alert('go to the ' + index + ' slide');
});
Upvotes: 2
Reputation: 106332
In your code example i
is basically a global variable. By the time the alert()
code executes, i
has the maximum value of the for loop. The standard way to fix this problem in JavaScript is to create a new function which has its own scope to "hold" the variable around. Take for instance this code which returns your event handling function:
(function(i) { // using i as an argument here 'scopes' it
var something = i; // also within this function scope.
// inside here, both i and something will only ever reference the "local scope"
return function() {
alert(i);
};
})(i); // and here we are calling that function with i = 1,2,3,...
Upvotes: 1
Reputation: 1038720
You could use the eventData of the bind function:
for (var i = 1; i <= slideHelpers.total; i++) {
$('<a href="#">' + i + '</a>').bind('click', { index: i }, function(arg) {
alert('go to the ' + arg.data.index + ' slide');
}).appendTo('.slideaccess');
}
Upvotes: 0
Reputation: 943185
You need to create a new scope, otherwise every function will reference the same i
. In JavaScript variables are scoped to functions.
var make_alert_message = function make_alert_message(num) {
return function () {
alert('go to the ' + num + ' slide');
};
}
for (var i = 1; i <= slideHelpers.total; i++) {
$('<a href="#">' + i + '</a>').bind(
'click', make_alert_message(i)
).appendTo('.slideaccess')
}
Upvotes: 1
Reputation: 655189
You can use an additional function that returns your function:
for (i=1;i <= slideHelpers.total; i++) {
$('<a href="#">' + i + '</a>').bind('click',
(function(i) {
return function() {
alert('go to the ' + i + ' slide');
};
})(i)
).appendTo('.slideaccess');
}
With this additional function, the inner i
in your alert
refers to the argument i
of that function and not to the i
of the outer scope.
Upvotes: 2