Synchronous animations in jQuery, not using callba

2019-05-02 14:17发布

I can't use callbacks because I have a scenario like this (pseudo-code):

$('.box').on('click', function() {
    $('.expanded-box').animate({
        // shrink it
    });

    $(this).animate({
        // grow it
        $(this).addClass('expanded-box');
    });
});

I can't put the expansion animation within the callback for the expanded-box growth animation because it may not always happen. But I need the second animation to wait till the previous one is done. How can I do this?

2条回答
Summer. ? 凉城
2楼-- · 2019-05-02 14:31

You can encapsulate the second animation's code in a function and then call that function from the callback of the first animation or call it if the first animation doesn't happen. Assuming the idea is to shrink some other control that had the "expanded-box" class from a previous click:

$('.box').on('click', function() {
    var $this = $(this),
        $exp = $(".expanded-box");

    function grow() {
       $this.animate({
           width: "200px", height: "100px"
       }).addClass('expanded-box');
    }

    if ($exp.length > 0) {
       $exp.animate({
           width: "100px", height: "50px"
       }, grow).removeClass("expanded-box");
    } else {
       grow();
    }        
});​

Demo: http://jsfiddle.net/PXddm/

查看更多
兄弟一词,经得起流年.
3楼-- · 2019-05-02 14:37

Since jQuery 1.6, you can use promise() to obtain a Promise object that will be resolved when all animations on a given element have completed. In addition, the documentation says:

Using .promise() on a collection with no active animation returns a resolved Promise.

Therefore, it's well-suited to your use case, and you can write:

$('.box').on('click', function() {
    var $this = $(this);
    $('.expanded-box').animate({
        // shrink it
    }).promise().done(function() {
        $this.animate({
            // grow it
        }).addClass('expanded-box');
    });
});
查看更多
登录 后发表回答