如何使用when()与多个延迟使效果非同步运行?

时间:2015-06-17 21:29:09

标签: javascript jquery jquery-effects

我正在编写一些简单的UI代码,以便在按下按钮时重新排列布局。

我有一个包含三个表单字段的搜索栏,一个"搜索"按钮,一些文字和一个标志。按下"搜索,"按钮,徽标和文本淡出,带有文本字段的栏使用jquery.animate()滑动到页面顶部,徽标和搜索按钮被赋予不同的CSS以重新定位它们,然后淡入新的位置。

我正在尝试使用此JQuery documentation

来使用deferred.done()

我从下面开始:

var fades = function () {
    $("#centerSearchText").fadeOut();
    $("#headerImage").fadeOut();
    $("#searchButton").fadeOut();
}

$.when( fades() ).done(function () {
    var positionUpdate = function() { 
        $("#headerImage").css({ "left": "12px", "margin-left": "12px", "margin-top": "12px", "float": "left" });
        $("#searchButton").appendTo("#search_input_table tr:first")
        $("#header").animate({
            top: "0px",
            marginTop: "0px",
        }, 500);
    }

    $.when(cssUpdate()).done(function () {
        $("#headerImage").fadeIn();
        $("#searchButton").fadeIn();
    });

});

...因为每个函数同时运行而无法正常工作。我意识到我没有正确地按照示例返回一个延迟对象,如下面的链接示例所示:

var effect = function() {
    return $( "div" ).fadeIn( 800 ).delay( 1200 ).fadeOut();
};

但是我需要在完成三个fadeOuts()时返回,而不是只返回一个。所以我将我的代码更新为以下内容:

var fades = function () {
    return $.when($("#centerSearchText").fadeOut(), $("#headerImage").fadeOut(), $("#searchbtn").fadeOut()).done()
}

$.when( fades() ).done(function () {
    var cssUpdate = function() { 
        return $.when($("#headerImage").css({ "left": "12px", "margin-left": "12px", "margin-top": "12px", "float": "left" }),
                    $("#searchbtn").appendTo("#search_input_table tr:first"),
                    $("#header").animate({
                        top: "0px",
                        marginTop: "0px",
                    }, 500)).done(); 
    }
    $.when(cssUpdate()).done(function () {
        $("#headerImage").fadeIn();
        $("#searchbtn").fadeIn();
    });

});

...其中UI元素不再同时运行其效果,因为在初始fadeOuts之后没有到达代码。

任何人都可以告诉我这里我做错了什么吗?我确定我误解了when()done()在某个地方的使用,但我还没有找到使用多个延迟对象进行比较的精彩文档我的代码。

3 个答案:

答案 0 :(得分:2)

您可以使用延期:

var deferred1 = $.Deferred();
var deferred2 = $.Deferred();
var deferred3 = $.Deferred();

$("#centerSearchText").fadeOut(1000, function() { deferred1.resolve(); } );
$("#headerImage").fadeOut(1000, function() { deferred2.resolve(); } );
$("#searchButton").fadeOut(1000, function() { deferred3.resolve(); } );


$.when(deferred1, deferred2, deferred3).done(function() {

    return when($("#headerImage").css({ "left": "12px", "margin-left": "12px", "margin-top": "12px", "float": "left" }),
                $("#searchbtn").appendTo("#search_input_table tr:first"),
                $("#header").animate({
                    top: "0px",
                    marginTop: "0px",
                }, 500)).done(); 
}
$.when(cssUpdate()).done(function () {
    $("#headerImage").fadeIn();
    $("#searchbtn").fadeIn();

});

http://api.jquery.com/category/deferred-object/

答案 1 :(得分:0)

有时在动画结束时更容易使用函数调用:

$("#header").animate(
{
    top: "0px",
    marginTop: "0px",
}, 500, function()
{
    // call next animation function here, it will be called upon completion
});

答案 2 :(得分:0)

鉴于您正在为所有三个元素使用未修改的.fadeOut()动画,更好的方法是将promises推送到数组中,并使用$.when()评估数组,例如:

// Define vars
var fades = [],
    cssUpdates = [],
    positionUpdate = function() { 
        $("#headerImage").css({ "left": "12px", "margin-left": "12px", "margin-top": "12px", "float": "left" });
        $("#searchButton").appendTo("#search_input_table tr:first")
        $("#header").animate({
            top: "0px",
            marginTop: "0px",
        }, 500);
    },
    cssUpdate = function() { 
        return when($("#headerImage").css({ "left": "12px", "margin-left": "12px", "margin-top": "12px", "float": "left" }),
                    $("#searchbtn").appendTo("#search_input_table tr:first"),
                    $("#header").animate({
                        top: "0px",
                        marginTop: "0px",
                    }, 500)).done(); 
    }

// Fade out
$("#centerSearchText, #headerImage, #searchButton").fadeOut(function() {
    var d = new $.Deferred();
    fades.push(d.resolve());
});

// Listen to fadeOut completion
$.when.apply($, fades).then(function() {
    $.when(cssUpdate()).then(function() {
        $("#headerImage, #searchbtn").fadeIn();
    })
});