使用jquery .when多个动画

时间:2012-11-16 11:53:36

标签: javascript jquery animation

我是jquery和js的新手所以也许这是一个愚蠢的问题。

我有两个动画:

$(foo2).fadeOut(1000);
$(foo1).fadeOut(2000);

我想要一个回调,当他们以一种优雅的方式完成时(可以扩展到任意数量的动画,具有不同的 - 并且不知道持续时间 - 可能使用.when)

到目前为止,我只在最长的动画中调用.when

function different_animation() {

  effect = function() {

   foo1 = 'div'; //this is an example that selects multiple elements
   foo2 = 'p'; //this is an example that selects multiple elements

    var ret1 = $(foo1).fadeOut(1000);
    var ret2 = $(foo2).fadeOut(2000);

    var seconds = new Date().getTime() / 1000;
    console.log('fade out at'+seconds);

    // i know that to ret2 there is attached a longer animation is longer then ret1
    return ret2; 
  }

  $.when( effect() ).done(function() {
    var seconds = new Date().getTime() / 1000;
    console.log('done at '+seconds);
  });
}

但如果有更多动画并且我不知道每个动画的时间怎么办?我需要能够加入其中的东西。

3 个答案:

答案 0 :(得分:1)

您可以利用$.DeferredfadeOut的回调功能来实现这一目标:

var deferred1 = $.Deferred();
var deferred2 = $.Deferred();
$(foo1).fadeOut(1000, function() { deferred1.resolve(); } );
$(foo2).fadeOut(2000, function() { deferred2.resolve(); } );

$.when(deferred1, deferred2).done(function() {
    console.log("both animations have completed");
});

这可以轻松扩展到任意数量的动画(以及一般的承诺)。您可以将任意数量的promises或deferred放入数组中并使用

$.when.apply(null, arrayOfPromises).done(callback);

在所有这些内容完成时触发callback

<强> See it in action

答案 1 :(得分:1)

根据jquery.Deferred()的{​​{3}},您可以将函数链接到数组中,如下所示:

var arrayOfAnimation = [];

effect = function() {

  foo1 = 'div'; //this is an example that selects multiple elements
  foo2 = 'p'; //this is an example that selects multiple elements

  var deferred1 = $.Deferred();
  var deferred2 = $.Deferred();
  $(foo1).fadeOut(1000, function() { deferred1.resolve(); } );
  $(foo2).fadeOut(2000, function() { deferred2.resolve(); } );

  arrayOfAnimation.push(deferred1);
  arrayOfAnimation.push(deferred2);

  var seconds = new Date().getTime() / 1000;
  console.log('fade out at'+seconds);
}

$.done(arrayOfAnimation)
.done()
.done(function() {
  var seconds = new Date().getTime() / 1000;
  console.log('done at '+seconds);
});

<强>更新
来自docs的示例:

<script>
/* 3 functions to call when the Deferred object is resolved */
function fn1() {
  $("p").append(" 1 ");
}
function fn2() {
  $("p").append(" 2 ");
}
function fn3(n) {
  $("p").append(n + " 3 " + n);
}

/* create a deferred object */
var dfd = $.Deferred();

/* add handlers to be called when dfd is resolved */
dfd
/* .done() can take any number of functions or arrays of functions */
.done( [fn1, fn2], fn3, [fn2, fn1] )
/* we can chain done methods, too */
.done(function(n) {
  $("p").append(n + " we're done.");
});

/* resolve the Deferred object when the button is clicked */
$("button").bind("click", function() {
  dfd.resolve("and");
});
</script>

答案 2 :(得分:1)

jQuery的.animate()和其他效果方法返回.when()方法中可用的对象,因此不必手动创建和解析延迟对象。

var promises = [];
promises.push($("#foo1").fadeOut(1000));
promises.push($("#foo2").fadeOut(2000));
$.when.apply(null, promises).done(function() { /* all done */ }); 

从这个版本的Jons jsfiddle可以看出:http://jsfiddle.net/2sJVX/55/