How to wait for effect queue to complete in jQuery call sequence

I am looking for some function that:

  • would be able to wait for all effects in the queue to finish
  • could be used in the classical jQuery call sequence
  • Example:

    I want to do some animations and then some operations after they finish:

    $('.obs_list')
    .delay(500)
    .animate({
            'background-color' : '#ffcc33'
    }, 200)
    .delay(1000)
    .animate({
            'background-color' : 'transparent'
    }, 2000)
    .THE_FUNCTION_I_AM_LOOKING_FOR() 
    .css({ 'color' : 'red' }) // this should come *after* the effects above are finished
    ...
    

    I want to avoid the complete callback of the animate function since you have to call jquery again inside it, it is not very elegant and breaks the chain:

    ...
    .animate({
            'background-color' : 'transparent'
    }, 2000, function () {
            $(this)
            .css({ 'color' : 'red' })
            ...
    });
    

    I hate this solution.

    I tried to use .promise() but this breaks the chain too as it apparently doesn't return the proper jQuery object. And please avoid writing new plugin :-)


    You have a few options:

    queue :

    .animate(...)
    .queue(function (n) {
        $(this).css('color', 'red');
        n();
    });
    

    The queue callback will be called once per element in the collection when each of them have reached this function in the queue. This means that the queue callback will be called multiple times, and possibly at different times if the items have differing animations.

    promise (with done ):

    .animate(...)
    .promise()
    .done(function () {
        $(this).css('color', 'red');
    });
    

    The done callback will be called once after all elements in the collection have emptied their queues completely. This is useful if you have a bunch of animations happening and you want to trigger something to happen when all of them have finished.

    A custom jQuery plugin:

    //I wrote this on the fly and it looks like it should work
    //I haven't tested it, so let me know if there are any bugs
    $.fn.queuedCSS = function () {
        var args = Array.prototype.slice.call(arguments);
        return this.queue(function (n) {
            $.fn.css.apply($(this), args);
            n();
        });
    };
    
    .animate(...)
    .queuedCSS('color', 'red');
    

    The complete callback of the animate call:

    .animate(..., function () {
        $(this).css('color', 'red');
    });
    

    When the specific animation on this specific element has finished, the complete callback will run.

    An animation that executes (almost) immediately:

    .animate(...)
    .animate({'color': 'red'}, 1);
    

    As the animation is part of the fx queue and the duration is so short as to be immediate, the animation will complete and set the styles.


    Now, I'm aware that you don't like any of these solutions, but that's too bad because they are the solutions. The css function does not interact with the fx queue, so if you want it to be part of the timed queue, you must use it within a callback in some way.


    Though it's not very elegant but it's a way to achieve the thing you want, try this code snippet :

    var elements = $('.obs_list');
    elements
    .delay(500)
    .animate({
            'background-color' : '#ffcc33'
        //see the use of proxy here to change the scope of callback function
    }, 200, $.proxy(function(){
            this
            .css({ 'color' : 'red' });
    }, elements)
    

    You can find more about proxy here.

    链接地址: http://www.djcxy.com/p/94878.html

    上一篇: 网格,JS

    下一篇: 如何等待效果队列在jQuery调用序列中完成