1

I have a jQuery function that looks like this:

$.get(urlCall, function (data) {
    $('#divId').children().fadeOut("slow", function() {
        $('#divId').append(data);
        $('#divId').fadeIn("slow");
    });
});

The problem is that it is calling the append and fadeIn lines once for EACH child under '#divId'. I was expecting the line

$('#divId').children().fadeOut("slow", function() {    

to fade out all children and then execute the function() a single time. But since it's executing the function() once for each child, I'm appending a lot of lines that I don't want appended.

I'm sure that there must be a way to say, "fade out all children, and then do X once", but I can't seem to figure out how to do it.

Help?

4

3 回答 3

7

你可以使用.promise()

$('#divId').children().fadeOut("slow").promise().done(function() {
    $('#divId').append(data);
    $('#divId').fadeIn("slow");
});

.promise() 方法返回一个动态生成的 Promise,一旦绑定到集合的特定类型的所有操作(无论是否排队)都结束,该 Promise 就会被解析。

默认情况下,type 为“fx”,这意味着返回的 Promise 在所选元素的所有动画都完成后解析。

对于downvoter

演示:小提琴

于 2013-10-17T16:26:38.087 回答
2

可靠地做到这一点的唯一方法是创建自己的函数来跟踪已完成的动画数量,并与原始动画的数量进行比较。就像是:

var target = $("#divId"),
    children = target.children();

$("#trigger").on("click", function () {
    toggleFadeAll(children, function () {
        $("#message").fadeToggle();
    });
});

function toggleFadeAll(els, callback) {
    var counter = 0,
        len = els.length;
    els.fadeToggle(function () {
        if (++counter === len) {
            callback.call(null);
        }
    });
}

演示:http: //jsfiddle.net/jbE3C/

(这显然需要根据您实际想要发生的动画进行调整)

toggleFadeAll调用所有fadeToggle动画完成后提供的回调。

当元素可能发生其他动画时,使用.promise()失败(不在正确的时间点执行所需的回调)。

于 2013-10-17T16:38:42.683 回答
1

Why not just separate the fading and the appending? So it would be

$.get(urlCall, function (data) {
    $('.someElement').each(function(){
         $('.fadeElement').fadeIn();

    });

    $('.otherElement').append(data)
});
于 2013-10-17T16:27:59.843 回答