Reputation: 169
Using the code below as an example, I want to pass the value 'i' to the callback function, so that it will remove the class from the correct div. At present, this just sees i as it's last value in the loop.
for(i=0;i<tablelength;i++){
if($('#detailsdiv'+i).is(':visible')){
$('#anotherdiv'+i).slideUp('slow',function(){
$('#div'+i).removeClass('open');
});
}
Upvotes: 0
Views: 298
Reputation: 2555
The reason why this is happening is quite simple: it takes time before the slide up function returns and the callback is called. Given the fact, function calls of this type are non blocking, for loop will fast get to the last value and all the callbacks will reference the last i
value.
Try this instead:
for (index=0; index < tablelength; index++) {
(function(i) {
if ($('#detailsdiv' + i).is(':visible')) {
$('#anotherdiv' + i).slideUp('slow', function() {
$('#div' + i).removeClass('open');
});
}
})(index);
}
This way, we create a function that is immediately invoked with a new scope that will hold up our variable. Each function is called with our for
loop iterator index
param and uses the i
variable inside it.
Upvotes: 2
Reputation: 776
You need to do it this way:
for(i=0;i<tablelength;i++){
if($('#detailsdiv'+i).is(':visible')){
(function(i){
$('#anotherdiv'+i).slideUp('slow',function(){
$('#div'+i).removeClass('open');
})(i);
});
}
This is due to the fact that the "i" that you use in the callback to slideUp will refer to the same variable in all the slideups that the for loop calls. And this "i" will of course after the loops execution have the value of the last iteration.
Using an IIFE (Immediately Invoked Function Expression) like this will capture the value of "i" at the moment the callback is set up.
Upvotes: 1