0

The problem

I'm trying to simplify a long javascript code and i have a problem with identifying callbacks.

I have a large array with elements to animate on page

[selector, activate interval, hide after]:

things_to_move = [
        ['.ufo, .chefoven, .sushi', 9900, 2000],
        ['.hotdog,.pizzaman,.boyballon', 12090, 3600],
        (...)
]

Basically, the aim is to to activate each of the selectors every x seconds, and hide them x seconds later, as per the example above.

Current code

After many tries, I ended up with this:

// Activate the element, and set timeout to hide it
var showFun = function(index1) {  
    $(things_to_move[index1][0]).addClass('move');      
    setTimeout( function(){hideFun(index1)},things_to_move[index1][2]);   
}
// Hide the element
var hideFun = function(index2) {   
     $(things_to_move[index2][0]).removeClass('move');  
} 

// Loop through all items and set the interval for each one
for(_A=0; _A < things_to_move.length; _A++) { 
    setInterval(function(){showFun(_A)}, things_to_move[_A][1]);    
}

But of course this doesn't work. Every time the showFun function is called, it takes the value of _A after the loop finished and not the value at which setInterval was set.

Question

So the question is, how can i pass a unique index into the setInterval callback, so the callback knows which array item to use?

Final solution

If anyone is interested, the final solution: Fiddle

Ramiz Wachtler
  • 5,623
  • 2
  • 28
  • 33
ZorleQ
  • 1,417
  • 13
  • 23
  • create a convenience/wrapper around setInterval eg. _setMyCallbackInterval_ and have that call setInterval as appropriate – amdixon Nov 14 '13 at 11:11
  • please provide jsfiddle if possible – Manish Parmar Nov 14 '13 at 11:13
  • possible duplicate of [Javascript infamous Loop problem?](http://stackoverflow.com/questions/1451009/javascript-infamous-loop-problem) and http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – bfavaretto Nov 14 '13 at 11:15

1 Answers1

3

The most direct way to solve it is using closures. Try something like this:

for(_A=0; _A < things_to_move.length; _A++) {
    setInterval((function(_innerA){
        return function(){ showFun(_innerA); };
    })(_A), things_to_move[_A][1]);
}
Stalinko
  • 3,319
  • 28
  • 31
  • Consider pulling the closure out of the `setInterval` and instead pass in `_innerA` as a param to `setInterval`. I think it would be a little bit cleaner. – thgaskell Nov 14 '13 at 11:19