1

我有两个函数,tick 和 tock。它们使 4 个数字先向一个方向旋转,然后再向另一个方向旋转。每个数字都可以以不同的速度缓解。

我可以调用这两个函数,但我不能让第二个(tock)等到所有数字都在第一个(tick)中移动完毕。

我已经查看了使用回调的其他类似问题,但我似乎无法用我的示例来实现这一点。我要么在第一个函数完成之前结束第二个函数,要么就像下面的代码一样,只使用第一个函数。

谢谢

$(document).ready(function(){
var complete = 0;

tick('', function(){tock();});

function tick(a){

    $('#col1 img')
        .delay('1000')
        .animate({bottom:'-=80px'},5000,'easeInOutSine');
        complete++;

    $('#col2 img')
        .delay('1000')
        .animate({bottom:'+=720px'},1000,'easeInOutSine');
        complete++;


    $('#col3 img')
        .delay('1000')
        .animate({bottom:'+=560px'},500,'easeInOutSine');
        complete++;


    $('#col4 img')
        .delay('1000')
        .animate({bottom:'-=240px'},2000,'easeInOutSine');
        complete++;

}

function tock(){
    $('#col1 img')
        .delay('1000')
        .animate({bottom:'+=80px'},2000,'easeInOutSine');

    $('#col2 img')
        .delay('1000')
        .animate({bottom:'-=720px'},2000,'easeInOutSine');

    $('#col3 img')
        .delay('1000')
        .animate({bottom:'-=560px'},2000,'easeInOutSine');

    $('#col4 img')
        .delay('1000')
        .animate({bottom:'+=240px'},2000,'easeInOutSine');
}
});
4

1 回答 1

4

您必须等到所有动画都完成后再调用另一个函数。所有 jQuery 对象都实现了Promise 接口[docs],并且在任何动画完成时它们都会被解析。与$.when [docs]一起,您可以轻松实现您想要的:

function tick(callback){

    var p1 = $('#col1 img')
        .delay('1000')
        .animate({bottom:'-=80px'},5000,'easeInOutSine')
        .promise();

    var p2 = $('#col2 img')
        .delay('1000')
        .animate({bottom:'+=720px'},1000,'easeInOutSine')
        .promise();


    var p3 = $('#col3 img')
        .delay('1000')
        .animate({bottom:'+=560px'},500,'easeInOutSine')
        .promise();


    var p4 = $('#col4 img')
        .delay('1000')
        .animate({bottom:'-=240px'},2000,'easeInOutSine')
        .promise();

    // $.when returns a new promise which is resolved once each passed promise 
    // is successfully resolved
    $.when(p1, p2, p3, p4).done(callback);
}

function tock(){
    // same as the original code
}

tick(tock);

有关承诺/延迟的更多信息:http: //api.jquery.com/category/deferred-object/


由于如此多的代码重复让我感到焦虑,这里是该tick函数的重构版本:

function tick(callback) {
    var data = [
        {props: {bottom: '-=80px'}, duration: 5000},
        {props: {bottom: '+=720px'}, duration: 1000},
        {props: {bottom: '+=560px'}, duration: 500},
        {props: {bottom: '-=240px'}, duration: 2000}
    ];
    var promises = [];

    // assuming the elements are in the correct document order
    $('#col1, #col2, #col3, #col4').find('img').each(function(i) {
        var d = data[i];
        promises.push(
            $(this).delay(1000).animate(d.props, d.duration, 'easeInOutSine').promise()
        );
    });

    $.when.apply($, promises).done(callback);
}
于 2013-06-13T15:41:15.737 回答