【问题标题】:Avoiding many nested callbacks when animating multiple objects为多个对象设置动画时避免许多嵌套回调
【发布时间】:2011-09-13 07:43:13
【问题描述】:

我需要在一个循环中一张一张地为 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);                                  
                                                    });                                         

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

【问题讨论】:

  • 我从您的问题中删除了所有粗体文本。不客气。
  • 看看这个 - stackoverflow.com/questions/6126/… @Andrew -
  • @Andrew 非常感谢...下次我会关心的。
  • @Rob 如果不是我的问题。我的代码看起来很丑,因为我不得不使用太多的动画回调:(
  • 到目前为止,我从肖恩那里得到了答案。但如果有人可以帮助我优化它,将不胜感激。

标签: javascript jquery queue jquery-animate


【解决方案1】:

对于更易于阅读和维护的版本,您可以使用 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?

【讨论】:

  • 我真的很喜欢你提到的插件,但不幸的是我正在开发的网站使用的是 jQuery 1.6.x。 ...感谢肖恩的支持
  • @Imran 答案更新为不需要插件且适用于 1.6.3 的版本
  • 是的,这很好用。我感谢你的努力。竖起两个大拇指。
猜你喜欢
  • 1970-01-01
  • 2018-10-29
  • 2020-08-18
  • 2011-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-30
  • 2012-02-05
相关资源
最近更新 更多