jQuery动画循环

6

我有一个关于动画循环的问题。有一个物体我想以特定方式移动并且以循环方式进行。是否有本地选项可以实现它?我目前有以下代码:

$(function () {
    function runIt() {
        $('#div').show("slow");
        $('#div').animate({"marginLeft":"300px"},8000);
        $('#div').animate({"marginLeft":"0px"},8000);
        $('#div').hide("slow", runIt);
    }
    runIt();
});

但看起来并不那么美观。

看起来非常不错。kingjiv的答案缩进得更好,看起来甚至更好。 - Jordan
kingjiv的解决方案看起来很有可能,我唯一要补充的是考虑在animate函数内允许的'onComplete'函数。请查看jQuery Api文档以获取更多信息! - Chris
我在我的回答中添加了一个链接,链接到我使用小插件和自定义队列的旧版fiddle。希望能有所帮助! :) - mekwall
2个回答

17

这是排队动画的正确方法。但是,你可以对代码进行一些修改,使它更加流畅和美观:

  • 将选定元素的引用存储在本地变量中以加快执行速度(减少对DOM的查询)
  • 通过删除对象属性的不必要引号来清理代码
  • 默认情况下,大小是以像素为单位测量的,因此我们可以使用纯整数
  • 可以用立即调用的匿名函数替换命名函数,然后使用arguments.callee作为回调函数

以下是一个示例,展示了上述更改:

$(function () {
    var element = $("#div");
    (function(){
        element
            .show("slow")
            .animate({ marginLeft: 300 }, 1000)
            .animate({ marginLeft: 0 },   1000)
            .hide("slow", arguments.callee);
    }());
});

你也可以通过创建自己的插件并使用自定义队列来以更高级的方式完成它。我曾经闲逛时创建了一个 小范例,涉及动画队列。

有关立即调用函数表达式(IIFE)的更多信息可阅读 Ben "Cowboy" Alman's 博客


在更通用的情况下,可以将arguments.callee();作为单独的一行进行调用。 - Robin Manoli

16

这就是我会做的。唯一的建议是使用链式语法以获得更好的代码,并且jquery对象不会每次都被创建。

$(function () {
   function runIt() {
      $('#div').show("slow")
               .animate({"marginLeft":"300px"},8000)
               .animate({"marginLeft":"0px"},8000)
               .hide("slow", runIt);
   }

   runIt();
});

谢谢您的建议。但是有没有其他更优美的方法来完成相同的事情,而不使用回调函数的hack呢? - Anton
5
在我看来,这不是黑客行为,而是最好的方法。当动画完成后,你可以重新开始它。我所能想到的另一种方法是使用setTimeout或setInterval,但那太丑陋了。你必须找出动画运行的时间并将超时设置为该时间...很丑陋。 - James Montagne
@Chris 是的,谢谢。我编辑代码时不是故意把它们留下来的。 - James Montagne
1
@AlexFord 不会的。这不是真正的递归。对runIt的调用完成后,下一次对runIt的调用被称为回调函数,在此时第一个runIt已经完成并离开了堆栈。 - James Montagne
我有两个函数互相递归调用。这里有一个很好的解决方案。 - Michael J. Calkins
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接