Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/409.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript jQuery动画里面的递归函数非常慢_Javascript_Jquery_Html - Fatal编程技术网

Javascript jQuery动画里面的递归函数非常慢

Javascript jQuery动画里面的递归函数非常慢,javascript,jquery,html,Javascript,Jquery,Html,我有一个箭头在三张汽车图片上水平反弹的小动画。箭头从每次反弹200ms开始,每转一圈时间增加200ms,直到在3号车的第7圈停止 它在Chrome和Firefox上几乎可以顺利运行。在Safari 7上,它起步很快,两圈后速度变得很慢,跳过了很多帧 Javascript代码如下所示: var fwd = true; var cnt = 6; var time = 200; function play(){ var tgt = fwd ? '310px' : '10px'; $

我有一个箭头在三张汽车图片上水平反弹的小动画。箭头从每次反弹200ms开始,每转一圈时间增加200ms,直到在3号车的第7圈停止

它在Chrome和Firefox上几乎可以顺利运行。在Safari 7上,它起步很快,两圈后速度变得很慢,跳过了很多帧

Javascript代码如下所示:

var fwd = true;
var cnt = 6;
var time = 200;

function play(){
    var tgt = fwd ? '310px' : '10px';

    $('#arrow').animate({left: tgt}, time, function() {
        if (cnt > 0){
            cnt--;
            fwd = !fwd;
            time += 200;
            play();
        } else {
            finalTarget();
        }
    });

}

function finalTarget (){
    $('#arrow').animate({left: '230px'}, 466, function(){
        $('#car3').hide(0).show('pulsate', {times: 3}, 600, function(){
            $('#car1, #car2').fadeTo('slow', 0.3);
        });
    });
}
代码也在JSFIDLE上

这个代码有什么问题

我不应该在回调函数中调用“play”函数吗

编辑
正如@jfriend00在注释中指出的,这段代码没有递归。“当调用动画完成函数并再次调用
play()
时,
play()
的原始调用早已完成。”

执行“循环”动画样式的典型方法是在回调中交替使用动画函数

我修改了你提供的小提琴:

Jquery:

cnt = 6;

var arrowSpeed = 400;
bounceLeft = function(){
        $("#arrow").animate({left: "+=380px"},{duration:arrowSpeed, complete: bounceRight});
    }
    bounceRight = function(){
        cnt--;
        if(cnt>0){
            $("#arrow").animate({left: "-=380px"},{duration:arrowSpeed, complete: bounceLeft});}else{
            finalTarget();
            }
    }
bounceLeft();


function finalTarget (){
    $('#arrow').animate({left: '230px'}, 466, function(){
        $('#car3').hide(0).show('pulsate', {times: 3}, 600, function(){
            $('#car1, #car2').fadeTo('slow', 0.3);
        });
    });
}

动画是一样的,但我认为我错误地判断了动画的宽度;还将其切换到“打开文档”。只需一个按钮即可轻松切换回“就绪”功能。

您的代码需要大量重新绘制。如果您想要平滑的动画,请使用CSS关键帧…使其静音。这也是波涛汹涌吗@KevinB否。这在safari上运行平稳。@jon与
setTimeout(play,0)
@jon没有区别-动画完成函数(对
play()
的连续调用源自此函数)本身已经由计时器调用,因此更改为
setTimeout(play,0)
将不会解决任何问题,并会增加15毫秒左右的延迟。好的,这个实现比我的更好,但我在我的示例中也使用了回调,在您的示例中也使用了递归,但分两步进行。问题是,在Safari上的结果是一样的。从这个意义上说,回调是很奇怪的,我确实在每次完成时调用另一个函数,但这些都是不同的函数,您的回调调用的是封装动画和调用的函数;本质上,我猜[Play()开始->Animate()开始->Animate()结束->回调->Play()开始],因此你永远不会真正“完成”Play()调用,因此会产生开销。OP的代码不是递归的。当调用动画完成函数并再次调用
play()
时,
play()
的原始调用早已完成。正在从jQuery计时器调用
play()
的连续调用。这不是递归的。通过读取代码,它看起来是递归的,但由于完成函数是异步的,并且在最初调用
play()
完成后的某个时间发生,因此这不是递归,以这种方式调用本身不会导致任何资源的积累。@jfriend00是正确的。我从来没有这样想过,但我的代码和@Culyx的代码都不是递归的。
play
函数在完成后被调用。我将编辑这个问题。@jfriend00解释得很好,仍然不确定性能上的差异是什么,也请编辑我的帖子