在动画化多个对象时避免许多嵌套回调

时间:2011-09-13 07:43:13

标签: javascript jquery queue jquery-animate

我需要在一个循环中逐个动画显示3个图像的不透明度...我编写下面的代码并且它工作正常但是这个代码很好或者我们可以优化它。请随便。

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 个答案:

答案 0 :(得分:2)

对于更易于阅读和维护的版本,您可以使用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()示例的全面说明,请查看以下答案:What are queues in jQuery?