I have a loop that animates 16 different elements, by getting values as an array. That part works, and it currently animates properly.

I want to call a function after every single animation is done.

//loop through the grid
    for (var y = 0; y < grid.length; y++) {
        for (var x = 0; x < grid[y].length; x++) {

            //if its not an empty space
            if (grid[y][x].type != 0) {

                $('#ent'+grid[y][x].entNum).animate({
                    left: (x*16*zoom)+'px',
                    top: ((1+(+y))*16*zoom)+'px'
                },{duration: 100,queue:false,complete:function(){ //end of animation
                    //doesn't really work here
                    okayToMove = true;
                }});

            }
        }
    }

You can see that I want to set okayToMove = true after the animation is finished, but as I currently have it, it will set that variable 16 times, and it will be true after the first one is finished, rather than the last one.

Any ideas?

有帮助吗?

解决方案 2

What about using a counter for the number of animations

var animations = 0;
for (var y = 0; y < grid.length; y++) {
    for (var x = 0; x < grid[y].length; x++) {

        //if its not an empty space
        if (grid[y][x].type != 0) {

            animations++;
            $('#ent'+grid[y][x].entNum).animate({
                left: (x*16*zoom)+'px',
                top: ((1+(+y))*16*zoom)+'px'
            },{duration: 100,queue:false,complete:function(){ //end of animation
                //doesn't really work here
                animations--;
            }});

        }
    }
}

Every time an animations starts, the counter is incremented and in the callback of each animation, the counter is decremented. This way as soon as the first animation started, you can monitor the value of the counter and when it reaches 0 again, you know the last animation is finished.

其他提示

You can achieve this using jQuery $.Deferred

var deferreds = [];


//loop through the grid
    for (var y = 0; y < grid.length; y++) {
        for (var x = 0; x < grid[y].length; x++) {

            //if its not an empty space
            if (grid[y][x].type != 0) {
                var def = new $.Deferred();    
                deferreds.push(def);
                (function(defferdToResolve){
                   $('#ent'+grid[y][x].entNum).animate({
                    left: (x*16*zoom)+'px',
                    top: ((1+(+y))*16*zoom)+'px'
                    },{duration: 100,queue:false,complete:function(){ //end of animation
                    //doesn't really work here
                    defferdToResolve.resolve();
                    }});
                })(def);


            }
        }
    }

This will be the handler for when all of the promises are resolved (i.e. all animations invoked the call back).

$.when.apply($, deferreds).done(function(){
  alert('All animations are done at this point!');
});

To illustrate $.Deferred better here is the codepen

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top