0

I have a for loop that cycles through the elements of an Array, constructs a jQuery target, applies a class to it and then removes it.

The class remove triggers a css3 @keyframes animation that takes 0.2 seconds. It then proceeds to actually remove the DOM element. This works in theory.

for (var i = playerBuffs.length - 1; i >= 0; i--) {

    var target = '#bufflist-' + playerBuffs[i][5];
    $(target).addClass('remove');
    setTimeout(function(){$(target).remove();},200);

};

There are conditions that have to be true in order for the element to be removed (i didn't paste that code here for simplicity), so sometimes there will be several elements to remove.

However, in that case, the loop runs this code once, sets the timeout, and then instantly reruns the code. So at the point in time where the timeout triggers, the target variable already changed. How do i fix this?

JKunstwald
  • 560
  • 1
  • 3
  • 14
  • 2
    Are you just trying to queue the animations, if so use `200*i` as the timeout ? – adeneo Jun 11 '14 at 17:33
  • This might help. http://stackoverflow.com/questions/111102/how-do-javascript-closures-work?rq=1 – Praveen Reddy Jun 11 '14 at 17:34
  • Another relevant question: http://stackoverflow.com/questions/1451009/javascript-infamous-loop-issue – Barmar Jun 11 '14 at 17:35
  • 1
    And yes, there's no special scope in a for loop, so the variable `target` is overwritten each time. As you're using jQuery, just using $.each would be the simple fix. – adeneo Jun 11 '14 at 17:35
  • 1
    I did not search properly before asking this it seems, the first few results weren't what i was looking for so i asked this, thanks for referring to the other question Ian! – JKunstwald Jun 11 '14 at 17:37
  • Why was this reopened? It's a duplicate of the many loop/closure problems – Ian Jun 11 '14 at 17:37
  • @adeneo Could you give a brief example? – JKunstwald Jun 11 '14 at 17:38
  • @JonJomate there has already been an answer posted, you should revise/check it, see it if it works, if it does not work, ***please*** leave some comment to notify the answerer. He may then try editing the answer to help you. I don't quite understand why ***many many*** askers ignore the answers in a very hard-to-understand way. It's not really friendly, unless you had choosed the best answer. In case you've found some answer elsewhere yourself, posting it as your own answer is also recommended. – King King Jun 11 '14 at 18:11

1 Answers1

0

target is being closed around the function with the loop, not the loop itself.

for (var i = playerBuffs.length - 1; i >= 0; i--) {

    var target = '#bufflist-' + playerBuffs[i][5];
    (function(target) {
       $(target).addClass('remove');
       setTimeout(function(){$(target).remove();},200);
    })(target);

};
Daniel A. White
  • 187,200
  • 47
  • 362
  • 445