如何检测jQuery中许多元素的多个同时动画的完成?

时间:2011-12-05 20:28:02

标签: jquery

我有一个相当复杂的设置,有两列完整的元素。 单击一个元素可打开其下的“详细信息”部分,关闭此列中任何其他先前打开的详细信息部分,过滤另一个列表并在另一列的其余元素下打开“详细信息”部分。

这对用户来说相当沉重,所以我试图动画所有这些并将其分成许多步骤或波形,以便用户可以理解发生了什么。

第1波:同时

  • 关闭所有元素下的详细信息部分
  • 淡化隐藏的元素

第2波:同时

  • 打开点击元素的详细信息部分
  • 淡出另一栏中的某些元素

第3波:同时

  • 在另一列的其余元素下打开详细信息部分

我通常使用animate方法的回调函数在第一个动画完成时启动第二个动画,但由于我等待多个动画完成,这种方法不起作用。此外,这些动画会影响许多元素,因此使用queue: false并不完全适合该法案。

如何检测多个元素上多个同步动画的完成情况?

4 个答案:

答案 0 :(得分:3)

对于您正在开始的每个动画,创建一个jQuery延迟对象:

var animDf1 = jQuery.Deferred();
var animDf2 = jQuery.Deferred();
...

在动画的回调中,解决该回调:

$('#thing1').fadeOut(500, function() {
    var animDf1.resolve();
});

将每组延迟对象与'when'函数组合:

// Wave 1:
$.when(animDf1, animDf2, animDf3, ...).then(function() {
    // They are all done.  Time for the next thing
    Wave2Start();
});

请记住,延期只能被解决(或拒绝)一次。如果所有这些动画都重复出现,则需要创建新的jQuery.Deferred对象以便下次处理。

更新:正如idanzalz的评论中所提到的,您可能不需要创建单独的延迟对象,因为您可以使用动画函数本身的返回作为延迟对象:

var animDf1 = $('#thing1').fadeOut(500);
var animDf2 = $('#thing2').fadeOut(500);

$.when(animDf1, animDf2).then(function() {
    // animations are done... what's next?
});

您是否可以使用此方法取决于您的代码结构,以及您是否将多个动画应用于同一个对象。我上面的第一个建议让你可以明确地控制每个.resolve()。

答案 1 :(得分:2)

使用jQuery的“when”和“done”方法。它们可以用于聚合多个“延迟”对象,就像动画返回的对象一样。 示例:

$.when(
   $('#A').animate({height : 100}), 
   $('#B').animate({width : 50})
).done(function() { alert('All Done!') })

答案 2 :(得分:0)

使用setInterval查询有问题的元素,看看:animated是否为真。

答案 3 :(得分:0)

使用初始化为0的全局计数器。当动画开始递增时。当动画完成递减并且它返回0时,运行在所有动画完成时应执行的主处理程序。