【问题标题】:jQuery queue, how does it work EXACTLY?jQuery 队列,它是如何工作的?
【发布时间】:2011-10-19 16:35:39
【问题描述】:

我很难弄清楚队列在 jQuery 中是如何工作的,尤其是 fx 队列。我想做的是:

一个接一个地为多个不同的元素制作动画

先看看this fiddle。当您单击该按钮时,这两个元素都会被动画化。现在我知道我可以做类似this fiddle 的事情,我将动画放在第一个动画的回调中,但这不是一个选择,因为我有一个动画池,我想任意以特定顺序运行它们中的任何一个。例如,我可能有动画 A、B、C、D 和 E,它们都为不同的元素设置动画。有时我想按 B->A->C 的顺序执行,有时我可能想要 A->B->C。

如何使用队列来实现此功能?

【问题讨论】:

    标签: javascript jquery queue jquery-animate


    【解决方案1】:

    由于您的动画正在移动不同的元素,因此您最好管理自己的队列而不是使用 jquery。您可以将要运行的动画存储在一个数组中。

    animations = [animation_a, animation_b, animation_c];
    

    然后在每个动画结束时调用运行下一个动画的函数。喜欢:

    function run_next() {
        if ( animations.length > 0 ) {
            next_animation = animations.shift();
            next_animation();
        }
    }
    
    function animation_a() {
        $("#element1").slideDown(500, run_next);
    } 
    
    function animation_b() {
        $("#element2").animate({left:'-=200'},1500, run_next);
    } 
    

    this fiddle

    【讨论】:

    • 这很不错,我想象的解决方案应该是这样的,基本上是在彼此的回调中链接动画。我对这种方法的不满是动画回调中的run_next。似乎有点侵入性,并在实际动画与队列之间产生了强烈的耦合。在我的完美世界中,我只有动画,A、B、C,不与任何其他对象耦合,我可以将它们放入队列中,队列会适当地处理它们。
    • 当然可以将动画与队列分离。您可以创建一个队列对象,每个动画都可以是一个知道它附加到哪个队列的闭包。但这需要更多的代码和复杂性。你真的需要那个吗?
    • @Leopd:这个方法还是不行,两个动画同时调用;它看起来排队的唯一原因是因为您将第一个动画设置为比第二个快。我输入了日志记录,以便您可以看到同时触发的所有功能。要让它排队,你需要一个等待算法,类似于我帖子中的算法
    • 它确实有效:jsfiddle.net/UGsrA/8。当 Vinceh 尝试在小提琴中实施我的建议时,我将原来的帖子中的“如果”改为了“一段时间”,直到现在我才修复它。
    【解决方案2】:

    假设您拥有所有 A、B、C...N 具有相同的类,只是为了在数组中选择它们。

    每个元素都有你想要使用的动画属性。

    就像我们有一个 DIVs :

    <div class="animateMe" properties="{Left: +=50}" duration="2000", easing="linear"></div>
    <div class="animateMe" properties="{Top: +=50}" duration="1000", easing="linear"></div>
    

    然后选择所有的DIV就像。

    var elements = $('div.animateMe') // Get all the objects in an array
    

    现在有一个 jQuery shuffle 插件可以帮助你打乱你选择的数组。

    elements = $.shuffle( elements );
    

    现在您可以使用.each() 函数单独制作动画。

    $.each( elements, function(){
        var properties = this.attr('properties');
        var duration= this.attr('duration');
        var easing= this.attr('easing');
        this.animate( properties, duration, easing );
    });
    

    【讨论】:

    • 必须为我想要动画的每个元素添加一个特定的类似乎有点奇怪。
    • 这只是一个大概的想法。公共类仅用于选择元素 A,B....N。而已。它可以通过许多其他方式来实现。
    【解决方案3】:

    更新(工作)

    下面的代码可以满足您的需求;它基于 Leopd 的自定义队列。但它不使用 jQuery 的队列或延迟对象:http://jsfiddle.net/rkw79/FPGrj/

    var q = ['div1', 'div2', 'div3', 'div4'];
    var next_div = q.shift();
    
    $("button").click( function() {
        animate_div();
    });
    
    function animate_div() {
        if ( q.length > 0 ) {
            curr_div = next_div;
            next_div = q.shift();
            $('#' + curr_div).hide(2000,animate_div);
        }
        else {
            $('#' + next_div).hide(2000);
        }
    } 
    



    划掉的代码是使用延迟对象的原始解决方案。它不会产生 OP 所需的功能。它只是用于缩短将多个动画链接到单个对象所需的代码量;它确实用于跨多个对象

    链接动画

    你想使用deferred objects。对于您的情况,这特别容易,因为动画已经在创建 promise 对象:http://jsfiddle.net/rkw79/fpseA/

    $("button").click( function() {
        $('#div1').growWidth().growHeight();
    });
    
    $.fn.growWidth = function () {
        return this.animate({width: 200});
    }
    
    $.fn.growHeight = function () {
       return this.animate({height: 200});
    }
    

    【讨论】:

    • 你是对的,它对你的问题没有帮助。队列对象似乎被封装在动画对象中。如果您能找到一种方法将该队列附加到另一个对象,例如父 div,它将解决问题。如果我发现一种方法可以做到这一点,我会更新。
    • @vinceh:检查更新。它有一个工作队列。如果我有时间,我会看看我是否可以将其实现到扩展中
    猜你喜欢
    • 2010-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    • 2013-04-13
    • 1970-01-01
    相关资源
    最近更新 更多