【问题标题】:Stopping specific jQuery animations停止特定的 jQuery 动画
【发布时间】:2011-06-24 09:38:26
【问题描述】:

我在单个对象上有多个动画,我需要停止特定动画而不是所有动画。 .stop() 方法似乎无法做到这一点。

例如,当同时为不透明度和宽度设置动画时,我可能需要在完成宽度动画的同时取消不透明度动画。这似乎是不可能的,但我希望有人知道我缺少的技巧或 API 调用。

注意:我不是在谈论排队动画,我希望同时为多个属性设置动画,并能够在其中一些属性动画已经开始后停止它们 p>

【问题讨论】:

  • 我原以为会有一种使用自定义命名队列的方法,但似乎.stop() 方法不能针对特定队列(据我所知)。跨度>
  • 现在我已经请求添加此功能bugs.jquery.com/ticket/8227
  • 停止动画的标准是什么?是否基于用户操作?

标签: jquery jquery-animate


【解决方案1】:

我讨厌成为一个回答自己问题的人(非常感谢详细的回答并投入脑力!)但我找到了直接的答案。显然,.animate() 方法有一个名为“queue”的参数,它默认为 true,但您可以设置为 false 以使动画立即发生。

这意味着通过将 queue 设置为 false,您可以使用单独的调用运行多个动画,而无需等待前一个完成。更好的是,如果您尝试为已设置动画的属性运行动画,则第二个将覆盖第一个。这意味着您可以停止属性的动画,只需使用队列“false”将其“动画化”为持续时间为 0 的当前值。

一个例子:

$myElement = $("#animateElement");
$myElement.animate({width: 500}, {duration: 5000});
$myElement.animate({height: 500}, {duration: 5000, queue: false});
// ... Wait 2 seconds ...
$myElement.animate({width: $myElement.width()}, {duration: 0, queue: false});

Another option 是由一位亲切的 jQuery 贡献者建议的,他回应了我的增强请求。这利用了在动画上使用阶跃函数的能力(在动画中的每个点都调用阶跃函数,您可以根据需要的任何标准来操纵动画参数)。虽然这也可以解决问题,但我觉得它比“queue: false”选项更脏。

【讨论】:

    【解决方案2】:

    在仔细考虑了这一点之后,我意识到由于 jQuery 中处理动画的方式,您要尝试做的事情并不容易。

    由于动画是由一个队列管理的,所以如果它们不在同一个函数中,就不可能在同一个元素上运行并发动画。

    也就是说,

    $(element).animate(aThing, aTime);
              .animate(anotherThing, anotherTime);
    

    不会并行运行。 aThing 将在 aTime 内结束,随后 anotherThing 将持续 anotherTime

    因此,您只能通过将它们放在同一个函数中来完成多个更改:

    $(element).animate({aThing: aValue, anotherThing: anotherValue}, aTime);
    

    这里简要解释一下在 jQuery 中如何处理动画函数。

    在动画期间为元素分配一个计时器对象:

    function t( gotoEnd ) {
        return self.step(gotoEnd);
    }
    
    t.elem = this.elem;
    jQuery.timers.push(t);
    

    当你调用停止函数时,它会从定时器中移除定时器:

    // go in reverse order so anything added to the queue during the loop is ignored
    for ( var i = timers.length - 1; i >= 0; i-- ) {
        if ( timers[i].elem === this ) {
            if (gotoEnd) {
                // force the next step to be the last
                timers[i](true);
            }
    
            timers.splice(i, 1);
        }
    }
    

    因此,由于计时器本身已被终止,因此无法删除动画函数的特定属性。


    我能想到的唯一方法是跟踪开始时间和持续时间,重新排队动画并停止当前动画。

    var start = $.now();
    var duration = 5000;
    
    $(element).animate({opacity: '0.5', width: '500px'}, duration);
    

    ...

    var remaining = duration - ($.now() - start);
    $(element).animate({opacity: '0.5', remaining)
              .stop();
    

    【讨论】:

    • 非常感谢您的回复!我可能不完全理解,但看起来这段代码会导致宽度动画持续 5 秒,此时不透明动画将开始。我需要能够同时运行宽度和不透明度动画(即宽度和不透明度都在变化),并且能够在完成之前停止其中一个或另一个而不停止两者。
    • 好吧,我已经修改了我的答案,因为我实际上对你的问题有了更好的理解:)。
    • 嗨,伊恩——我只是想非常感谢您提供如此详细的回答。我能够找到一个不需要任何跟踪的直接解决方案,所以很遗憾我不能给你答案标签:(。但希望有一天你能够使用这个解决方案!
    【解决方案3】:

    除了一个动画,你能不能把它分解成几个更小的动画(即动画不透明度从 0-20%,然后动画从 20-40%,然后 40-60%,等等)而不是 .stop()-正在播放动画,您只是不重新启动它吗?

    【讨论】:

      【解决方案4】:

      2013 年更新

      从 jQuery 1.7 开始,您可以将 .animate() 与命名队列一起使用,并使用 .stop(queuename) 仅停止队列中的那些动画。

      http://api.jquery.com/animate/
      http://api.jquery.com/stop/

      【讨论】:

        【解决方案5】:

        我正在使用 jQuery 循环插件在同一页面上使用各种不同的动画类型(擦除、随机播放、缩放等)为十几个幻灯片制作动画。然后,当您将鼠标悬停在每个幻灯片上时,我有自己的小脚本来稍微淡化图像:

        # This code stops all current animations on an element
        
        $(".box img").hover(
            function(){
                $(this).stop().fadeTo("slow",0.7);
            },
            function(){
                $(this).stop().fadeTo("fast",1);
            }
        );
        

        问题是.stop() 函数也停止了它跟踪的循环插件 - 我的擦除、随机播放和缩放在动画进行到一半时突然停止,导致页面断裂和错位。解决方案是实现您的队列“错误”想法:

        # This code suited me better - it leaves the other running animations untouched
        
        $(".box img").hover(
            function(){
                $(this).animate({opacity: 0.7}, {duration: 1000, queue: false});
            },
            function(){
                $(this).animate({opacity: 1}, {duration: 250, queue: false});
            }
        );
        

        【讨论】:

          猜你喜欢
          • 2022-12-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-06-24
          • 1970-01-01
          • 1970-01-01
          • 2014-04-23
          • 1970-01-01
          相关资源
          最近更新 更多