Поставить в очередь ряд эффектов синхронно с jquery

Есть ли более читаемый способ поставить в очередь ряд асинхронных эффектов, чтобы они выполнялись синхронно?

var element1 = $('#div1');
var element2 = $('#div2');

$(element2).hide();
$(element1).on('click',function(){   
    $(element1).fadeOut(1000,function(){
        $(element2).fadeIn(1000, function(){
            $(element2).hide();
            alert('hello');
        });
    });
}); 

2 ответа

Решение

Вы можете предотвратить более глубокий эффект вложения, если используете систему, основанную на обещаниях.

$.when(
    $(element1).fadeOut(1000)
).then(function () {
    return $(element2).fadeIn(1000);
}).then(function () {
    return $(element2).hide();
}).then(function () {
    return $(element1).fadeIn(1000);
}).then(function () {
    return $(element1).fadeOut(1000);
});

Демо: http://jsfiddle.net/tYhNq/1

Вы заметите, что это позволяет очень легко изменить порядок анимации.

"Уловка" в том, что $.when() Метод возвращает объект обещания, связанный с первой анимацией, поэтому вы можете просто связать связку .then() звонки, отмечая, что каждый then() обратный вызов должен возвращать результат своей анимации.

Конечно, вы можете напрямую связывать анимацию с одним и тем же элементом, например .fadeIn(100).fadeOut(100)...

Эта проблема называется " обратный вызов ада". В NodeJS у вас есть опция модуля async, чтобы "убежать" от него.

Я не нашел соответствующий вариант в jQuery.

Я предлагаю создать одну функцию для каждого эффекта, как показано ниже:

var element1 = $('#div1');
var element2 = $('#div2');

$(element2).hide();

var finished = function () { console.log(":-)"); }
var hide = function () { element2.hide(); finished(); }
var fadeIn = function () { element2.fadeIn(1000, hide); }
var clicked = function () { element1.fadeOut(1000, fadeIn); }

$(element1).on('click', clicked);

JSFIDDLE

Другие вопросы по тегам