Javascript 使用jquery。当使用多个动画时

Javascript 使用jquery。当使用多个动画时,javascript,jquery,animation,Javascript,Jquery,Animation,我不熟悉jquery和js,所以这可能是个愚蠢的问题 我有两个动画: $(foo2).fadeOut(1000); $(foo1).fadeOut(2000); 我希望在他们以某种优雅的方式完成时调用回调(可扩展到任意数量的动画,其持续时间不同且未知,可能使用.when) 到目前为止,我只在最长的动画中调用 function different_animation() { effect = function() { foo1 = 'div'; //this is an examp

我不熟悉jquery和js,所以这可能是个愚蠢的问题

我有两个动画:

$(foo2).fadeOut(1000);
$(foo1).fadeOut(2000);
我希望在他们以某种优雅的方式完成时调用回调(可扩展到任意数量的动画,其持续时间不同且未知,可能使用.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);
  });
}

但是如果有更多的动画,而我不知道每一个动画的时间,该怎么办?我需要一些可以加入RET的东西。

您可以通过利用
fadeOut的回调功能来做到这一点:

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");
});
这可以很容易地扩展到任意数量的动画(一般来说也是如此)。您可以将尽可能多的承诺或延期放入一个数组中并使用

$.when.apply(null, arrayOfPromises).done(callback);
在所有回调都完成时触发
回调

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

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);
});
更新:
文档中的示例:

<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>

/*解析延迟对象时要调用的3个函数*/
函数fn1(){
$(“p”)。附加(“1”);
}
函数fn2(){
$(“p”)。附加(“2”);
}
功能fn3(n){
$(“p”)。附加(n+“3”+n);
}
/*创建延迟对象*/
var dfd=$.Deferred();
/*添加解析dfd时要调用的处理程序*/
dfd
/*.done()可以接受任意数量的函数或函数数组*/
.完成([fn1,fn2],fn3,[fn2,fn1])
/*我们也可以链接完成的方法*/
.完成(功能(n){
$(“p”)。追加(n+“我们完成了”);
});
/*单击按钮时解析延迟对象*/
$(“按钮”).bind(“单击”,函数(){
dfd.决议(“和”);
});
jQuery的
.animate()
和其他效果方法返回一个在
.when()
方法中可用的对象,因此无需手动创建和解析延迟对象

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

从Jons JSFIDLE的这个版本中可以看出:

IMO,$。这不是一种优雅的方式。这就像jQuery的语法糖,它破坏了面向事件的范例。您可以使用Event.js或编写自己的事件订阅/发布工厂,并像蜜蜂一样执行:$(foo2).fadeOut(2000,onRet2AnimationDone);onRet2AnimationDone(函数(){alert(“DONE”);});它可以扩展到任意数量的动画吗?