Jquery——延迟回调直到多个动画完成

时间:2021-09-26 19:41:01

I need a callback to execute once after multiple elements have finished animating. My jquery selector is as follows:

我需要在多个元素完成动画后执行一次回调。我的jquery选择器如下:

$('.buttons').fadeIn('fast',function() {
   // my callback
});

The problem with this is that the buttons class matches a number of elements, all of which need to be faded in before the callback is executed. As it stands now, the callback is executed after each individual element has finished animating. This is NOT the desired function. I'm looking for an elegant solution such that my callback is only executed once after all the matched elements have finished animating. This question has popped up in a few places including SO, but there's never been an elegant answer (nor even a definitive answer for that matter - solutions that work for one person don't work at all for others).

这样做的问题是,buttons类与许多元素相匹配,在执行回调之前,所有这些元素都需要淡出。现在,回调在每个元素完成动画之后执行。这不是我们想要的函数。我正在寻找一种优雅的解决方案,以便在所有匹配的元素完成动画之后,回调只执行一次。这个问题已经出现在一些地方,包括SO,但从来没有一个优雅的答案(甚至也没有一个明确的答案——对一个人有效的解决方案对另一个人完全无效)。

6 个解决方案

#1


5  

An alternative to @Ross's answer that will always trigger the callback on the last button to fade in (which may or may not be the last button that was told to animate) could be:

对于@Ross的回答,另一种可能是:

var buttons = $(".buttons");
var numbuttons = buttons.length;
var i = 0;

buttons.fadeIn('fast', function() {
    i++;
    if(i == numbuttons) {
        //do your callback stuff
    }
});

#2


81  

jQuery introduced a promise in version 1.6 and is far more elegant than adding counters.

jQuery在1.6版本中引入了一个承诺,比添加计数器更加优雅。

Example:

例子:

// Step 1: Make your animation
$(".buttons").each(function() {
    $(this).fadeIn("fast");
});

// Step 2: Attach a promise to be called once animation is complete
$(".buttons").promise().done(function() {
    // my callback
});

#3


14  

For collecting unrelated element animations into a single callback you can do this:

要将不相关的元素动画收集到一个回调中,可以这样做:

$.when(
    $someElement.animate(...).promise(),
    $someOtherElement.animate(...).promise()
).done(function() {
    console.log("Both animations complete");
});

#4


1  

var $buttons = $('.buttons');

$buttons.each( function (index) { 
    if ( index == $buttons.length - 1 ) {
        $(this).fadeIn('fast',function() {
           // my callback
        });
    } else {
        $(this).fadeIn('fast');
    }
});

Untested but this should apply the callback to the last button only.

未测试,但这应该只对最后一个按钮应用回调。

#5


0  

The idea behind my solution is to keep a counter. Whenever an animation finishes, you simply increment this counter, thus you can see when you are at last button. Remember to set the counter back to zero when everything is done, because you might want to repeat this (hide them again, and show them again).

我的解决方案背后的想法是保留一个计数器。当动画完成时,您只需增加这个计数器,这样您就可以看到何时是最后一个按钮。当所有操作完成时,请记住将计数器设置为0,因为您可能希望重复这个操作(再次隐藏它们,并再次显示它们)。

var $buttons=$('.buttons'),
    button_n=$buttons.length,
    button_counter=0;
$buttons.fadeIn('fast', function () {
    if (button_counter==button_n-1) {
        alert('It is all done!');
        button_counter=0;
    } else {
        button_counter++;
    }
});

#6


0  

onClickBtnEdit = function(){
    var $EditDel = $($btnEdit).add($btnDel);
    var btns = $EditDel.size();

    $EditDel.fadeOut("def",function(){                   
        btns--;
        if(btns===0){
            $($btnSave).add($btnCancel).fadeIn("slow");
        }
    });
};

#1


5  

An alternative to @Ross's answer that will always trigger the callback on the last button to fade in (which may or may not be the last button that was told to animate) could be:

对于@Ross的回答,另一种可能是:

var buttons = $(".buttons");
var numbuttons = buttons.length;
var i = 0;

buttons.fadeIn('fast', function() {
    i++;
    if(i == numbuttons) {
        //do your callback stuff
    }
});

#2


81  

jQuery introduced a promise in version 1.6 and is far more elegant than adding counters.

jQuery在1.6版本中引入了一个承诺,比添加计数器更加优雅。

Example:

例子:

// Step 1: Make your animation
$(".buttons").each(function() {
    $(this).fadeIn("fast");
});

// Step 2: Attach a promise to be called once animation is complete
$(".buttons").promise().done(function() {
    // my callback
});

#3


14  

For collecting unrelated element animations into a single callback you can do this:

要将不相关的元素动画收集到一个回调中,可以这样做:

$.when(
    $someElement.animate(...).promise(),
    $someOtherElement.animate(...).promise()
).done(function() {
    console.log("Both animations complete");
});

#4


1  

var $buttons = $('.buttons');

$buttons.each( function (index) { 
    if ( index == $buttons.length - 1 ) {
        $(this).fadeIn('fast',function() {
           // my callback
        });
    } else {
        $(this).fadeIn('fast');
    }
});

Untested but this should apply the callback to the last button only.

未测试,但这应该只对最后一个按钮应用回调。

#5


0  

The idea behind my solution is to keep a counter. Whenever an animation finishes, you simply increment this counter, thus you can see when you are at last button. Remember to set the counter back to zero when everything is done, because you might want to repeat this (hide them again, and show them again).

我的解决方案背后的想法是保留一个计数器。当动画完成时,您只需增加这个计数器,这样您就可以看到何时是最后一个按钮。当所有操作完成时,请记住将计数器设置为0,因为您可能希望重复这个操作(再次隐藏它们,并再次显示它们)。

var $buttons=$('.buttons'),
    button_n=$buttons.length,
    button_counter=0;
$buttons.fadeIn('fast', function () {
    if (button_counter==button_n-1) {
        alert('It is all done!');
        button_counter=0;
    } else {
        button_counter++;
    }
});

#6


0  

onClickBtnEdit = function(){
    var $EditDel = $($btnEdit).add($btnDel);
    var btns = $EditDel.size();

    $EditDel.fadeOut("def",function(){                   
        btns--;
        if(btns===0){
            $($btnSave).add($btnCancel).fadeIn("slow");
        }
    });
};