不使用递归创建jquery无限动画

create jquery infinite animation not using recursion?

本文关键字:jquery 无限 动画 创建 递归      更新时间:2023-09-26

如何使用jquery创建无限动画,但不使用递归方式?

我找到的递归解决方案是:jQuery.animate()回调无限循环

使用递归的问题是:在制作动画时,当前页面的浏览器选项卡将占用越来越多的内存。

您实际上犯了一个错误,认为代码是"递归的"。它是而不是递归的。你的评论"当前页面的浏览器选项卡将占用越来越多的内存。"并不是因为该代码中有任何递归。如果你每秒都有内存泄漏(根据你的评论),那么问题就出在其他地方了。

代码的实例实际上是通过嵌套堆栈调用(即线性而非递归)按顺序运行的,而不是

使用您链接到的最基本的示例:

function start() {
    $('#element').animate({}, 5000, 'linear', start);
}
start();

实际情况如下:

  • 定义了一个名为start的函数,然后调用一次
  • start内部,动画操作启动,然后start立即退出
  • animate只是将信息添加到元素的单个动画队列中,然后返回
  • 动画队列由一个单独的进程(单个计时器等)一步一步地处理
  • 当排队的条目达到其预期的结束状态时,它会调用回调-存储在排队条目中的全局start函数
  • 这个简单操作在动画队列中添加另一个条目并退出

基本上,代码看起来是递归的,但由于操作是异步的,通过队列,不是递归的。我不知道这些是否有官方名称,所以我只称它们为链式回调。

更新测试结果

结论。。。所有方法都会消耗相同数量的内存,并且最终会被释放,不会永远构建,所以这并不是一个真正的问题

示例1

这是OP最初在Chrome中内存使用量增加时遇到的问题。

(function($){
    $(function(){  //document.ready
        function start() {
                $('#animate').animate({'margin-left':'150px'}, 1000, function () {
                    $(this).animate({'margin-left':'50px'}, 1000, 'linear', start);                
                });
        }
        start();
    });
})(jQuery);

示例2

当前的解决方案包括Bergi请求的回调,以避免setinterval中潜在的"漂移"。

(function($){
    $(function(){  //document.ready
    });
    (function customSwipe(element) {
        element
            .animate({"margin-left" : "150px"}, 1000)
            .animate({"margin-left" : "50px"}, 1000, function(){
                setTimeout(function(){
                    customSwipe(element);
                }, 2000);
            });
    })($('#animate'));
})(jQuery);

示例3

我给出的原始答案,使用setInterval()

(function($){
    $(function(){  //document.ready
            setInterval(function(){
                    $("#animate").animate({'margin-left':'150px'},1000);
                    $("#animate").animate({'margin-left':'50px'},1000);
            },2000); 
    });
})(jQuery);

骨架w/Jquery

空页面,只有#animate元素

(function($){
    $(function(){  //document.ready

    });
})(jQuery);

选项卡打开10分钟后的数据

CODE            STARTING    ENDED
Example 1       14.300k     19.996k
Example 2       14.300k     20.020k
Example 3       14.300k     20.344k
Skeleton w/ jQuery  14.300k     15.868k

有趣的是,没有做任何事情的代码仍然略微增加了使用量。这些值随着内存的使用和释放而上下浮动。另一件事是使用任务管理器中的"清除内存"按钮来查看有多少已用内存是等待收集的垃圾。

25分钟后的数据

Example 1       14.300k     18.640k
Example 2       14.300k     18.724k
Example 3       14.300k     18.876k
Skeleton w/ jQuery  14.300k     15.868k

结论。。。所有方法都会消耗相同数量的内存,并且最终会被释放,不会永远构建,所以这并不是一个真正的问题

因此,只使用最坚实、最合理的代码将是最好的选择,示例2将是我的选择。

使用回调更新

你试过用setTimeout$.animate()吗?

(function($){
    (function customSwipe(element) {
        element
            .animate({'margin-left':'150px'}, 1000)
            .animate({'margin-left':'50px'}, 1000, function(){
                setTimeout(function(){
                    customSwipe(element);
                }, 2000);
            });
    })($('#animate'));
    $(function(){  //document.ready

    });
})(jQuery);

如果不需要setTimeout()在动画之间延迟,请删除它。

JSFIDDLE的上述代码正在工作。。。

您可能还想了解更多复杂的动画。

http://api.jquery.com/jquery.fx.interval/

结论。。。所有方法都会消耗相同数量的内存,并且最终会被释放,不会永远构建,所以这并不是一个真正的问题

你在Chrome TM中看到的是,每次它触发动画时,都会请求那么多内存,操作系统会将这些内存"提交"给Chrome进行操作。操作完成后,内存仍处于提交状态。在某个时候,Chromes垃圾收集器会出现并释放内存,您的使用情况统计数据会回落。所以,如果你看得足够久,你会看到记忆上下浮动。

您可以将--purge memory按钮放在Chrome命令行的末尾,以便在Chrome TM中有一个purge memory按钮。这可能有助于您了解实际有多少内存等待释放。

希望这个答案能帮助你,也许还能帮助其他人。