Избегание многих вложенных обратных вызовов при анимации нескольких объектов - PullRequest
1 голос
/ 13 сентября 2011

Мне нужно анимировать непрозрачность трех изображений одно за другим в цикле ... Я пишу код ниже, и он работает нормально, но хорош этот код или мы можем его оптимизировать.Любые предложения, пожалуйста.

function animateit(play){
            if(play==false){
                $(".img2", obj).stop(true, true).fadeTo('800', 0);
                $(".img3", obj).stop(true, true).fadeTo('800', 0);              
                $(".img4", obj).stop(true, true).fadeTo('800', 0);                              
            }
            if(play==true){
                $(".img2", obj).animate({opacity:"1"}, s, e,
                    function(){
                        $(".img3", obj).delay(p).animate({opacity:"1"}, s, e,
                            function(){
                                $(".img2").css({opacity:"0"});

                                $(".img4", obj).delay(p).animate({opacity:"1"}, s, e,
                                    function(){
                                        $(".img3").css({opacity:"0"});
                                        $(".img4", obj).delay(p).animate({opacity:"0"}, s, e,
                                            function(){ 
                                                $(".img4", obj).delay(p).animate({opacity:"0"}, s, e,
                                                    function(){ 
                                                        if(play==true)animateit(true);                                  
                                                    });                                         

                                            });
                                    });
                                });
                        });
                }
            }

1 Ответ

2 голосов
/ 13 сентября 2011

Для версии, которую легче читать и поддерживать, вы можете использовать плагин jquery-fxQueues , который перегружает функцию $.animate() для поддержки глобальных очередей анимации.Это означает, что ваш код может быть написан просто как:

function animation() {
    var o2 = $(".img2", obj),
        o3 = $(".img3", obj),
        o4 = $(".img4", obj);
    o2.animate({opacity: "1"}, {duration:s, queue: "global", postDelay:p});
    o3.animate({opacity: "1"}, {duration:s, queue: "global"});
    o2.animate({opacity: "0"}, {duration:0, queue: "global", postDelay:p});
    o4.animate({opacity: "1"}, {duration:s, queue: "global"});
    o3.animate({opacity: "0"}, {duration:0, queue: "global", postDelay:p});
    o4.animate({opacity: "0"}, {duration:s, queue: "global", postDelay:p, 
                                complete:animation}); // repeat when done
}

Демонстрация, чтобы показать это в действии: http://jsfiddle.net/RMVtU/2/

Для справки, вот ваша версия в качестве скрипки: http://jsfiddle.net/dEfY7/

Важное примечание: У этого плагина есть потенциально огромный недостаток.Насколько я знаю, последняя версия fxQueues (2.0.3) работает только с jQuery 1.3.x.


Обновление (не плагин версия)

Если ограниченияfxQueues - прерыватель сделки, но все еще возможно накатить собственную глобальную очередь анимации, используя $.queue() и $.dequeue() на прокси-объекте.

Вотпример: http://jsfiddle.net/mAfFW/

/* functions to emulate a global queue */
var Q = $({}); // empty object to store global queue
var enQ = function(func) { Q.queue("global", func); } // add to queue
var deQ = function() { Q.dequeue("global"); }  // pop next animate
var stopQ = function() { Q.clearQueue("global"); }  // clear animation

function animate() {
    enQ(function() {
        o2.animate({opacity: "1"}, s, e, deQ);
    });
    enQ(function() {
        o3.delay(p).animate({opacity: "1"}, s, e, deQ);
    });
    enQ(function() {
        o2.css("opacity", "0");
        o4.delay(p).animate({opacity: "1"}, s, e, deQ);
    });
    enQ(function() {
        o3.css("opacity", "0");
        o4.delay(p).animate({opacity: "0"}, s, e, deQ);
    });
    enQ(function() {
        o3.css("opacity", "0");
        o4.delay(p).animate({opacity: "0"}, s, e, deQ);
    });
    enQ(animate); // repeat when done
    deQ();  // start the animation by dequeueing an entry
}

Это не так чисто, как использование fxQueues, но, безусловно, более читабельно, чем ряд вложенных обратных вызовов.

Для подробного объяснения $.queue() и $.dequeue() с примерами, проверьте этот ответ: Что такое очереди в jQuery?

...