完全执行 jQuery 动画而无需排队

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 $200 免费积分!

使用 jQuery 的 .animate() 函数时,它通常由 mouseEnter 或 hover 事件触发。 这很好,但意味着我们需要考虑这些事件被多次触发的情况。 如果附加了 hover 事件的元素被多次悬停,这意味着动画将被触发多次,这通常是不可取的。 处理此问题的标准方法是使用 .stop() 函数,例如

$(this).stop().animate({ width: "200px" });

但这绝对不是万能的解决方案。 让我们探索一下。

我们已经知道 **不** 使用 .stop() 会有问题,因为这样动画就会排队,对于多次快速悬停来说有点尴尬。 但不使用 .stop() 在某种程度上也很好,因为 mouseEnter 动画和 mouseLeave 动画完全按顺序执行。 我在这里追求的就是这种平滑度,只是没有排队。

使用 .stop() 可以防止排队,**但它也会阻止动画完成一个完整的循环。** 鼠标移开,stop 函数就会触发,停止触发 mouseEnter 的动画,并开始重置事物的动画。

我开始折腾的第一件事是在只使用其中一个动画之前使用 .stop(),但这没有太大帮助。 .stop() 函数还有一些你可以传递的参数,第二个参数决定是否应该先强制动画完成。 如果设置为 true,动画确实会完成,但它不会平滑地完成,它会跳到最终状态,我一般觉得这种效果不可取。

解决方案在于,**只有当元素的状态没有被动画化时才开始** 新动画。 这样,你甚至不用担心排队,因为一次只能运行一个动画。 可以用几种方法实现,但我发现这个是最干净的

$("div").hover(function(){
    $(this).filter(':not(:animated)').animate({ width: "200px" });
}, function() {
    $(this).animate({ width: "100px" });
});

在此过程中有很多想法。 查看下面的演示,了解我所经历的所有不同选项,以及一个同样有效的方法。

查看演示

更新:一定要看看 Ralf Stoltze 的 更好的解决方案.