2016-07-20 63 views
0

我希望动画可以连续运行,但控制台中总会出现错误:“VM1179:1 Uncaught ReferenceError:move is not defined”。不知道为什么......下面的代码复制setTimeout()函数不起作用

$(document).ready(function(){ 

    function move(){ 
     $("#block").animate({left:"+=50px" },1000).animate({top:"+=50px"},1000).animate({left:"-=20px"},1000).animate({top:"-=20px"}); 
     setTimeout('move()',1000); 
    } 
    move() 
}) 
+0

这是完美的工作。 – eronax59

+2

setTimeout在全局范围(浏览器内的窗口对象)中评估字符串'move()'。您的移动功能是本地发送给$(document).ready()的回调函数。 – progysm

+0

@progysm写了些什么。这是正确的答案。范围是你的问题 – eltonkamami

回答

1

当你使用一个字符串作为参数,如

setTimeout('move()',1000); 

setTimeout挑选来自全球范围内的功能(window,你的情况),但因为你是在document.ready参数函数中定义move(),它没有进入全球范围。

的解决方案是直接使用参考move函数作为参数向setTimeout

setTimeout(move, 1000); 

这样,它捡起来从本地范围,其中该函数存在。

-1

下面是你需要看到什么:

$(function(){ 

function ba(){ 
    $('#block').animate({left:'+=50px' }, 1000).animate({top:'+=50px'}, 1000).animate({left:"-=20px"}, 1000).animate({top:'-=20px'}, 1000); 
} 
function move(){ 
    ba(); 
    setTimeout(ba, 1000); 
} 
move(); 

}); 
+0

setTimeout需要在移动() – progysm

+0

我会解决它,坚持下去。 – PHPglue

+0

它与原始版本不同,因为它在第一次通话中等待1000毫秒。 – progysm

0

的downvoted答案是正确的。的setTimeout接受一个函数值(未调用的函数),而不是像你这样的调用函数有: setTimeout('move()',1000);

试试这个: setTimeout(move,1000);

+0

这是一个字符串仍然在你的答案。 – PHPglue

+1

@PHPglue谢谢,修正了 – aeb0

-2

不宜代码是这样的


$(document).ready(function(){ function move(){ console.log("hu"); } setTimeout(move(),1000); })

+1

setTimeout接受一个字符串或函数。您正在运行move()并返回undefined。 – progysm

+0

你甚至在下来投票和评论之前试过运行这段代码吗 –

+0

是的,我还阅读了MDN上setTimeout的文档:https://developer.mozilla.org/en/docs/Web/API/WindowTimers/setTimeout 。 setTimeout使用函数或字符串,而不是未定义的值。 – progysm

1

由于我发现你的脚本运行良好。但你可以这样做。

$(document).ready(function(){ 
    move(); 
}); 

function move(){ 
     $("#block").animate({left:"+=50px" },1000).animate({top:"+=50px"},1000).animate({left:"-=20px"},1000).animate({top:"-=20px"}); 
     setTimeout('move()',1000); 
} 
0

要每秒调用一个函数,您可以使用。

<script type="text/javascript"> 
     $(document).ready(function(){ 

      function move(){ 
       console.log("Called"); 
       $("#block").animate({left:"+=50px" },1000).animate({top:"+=50px"},1000).animate({left:"-=20px"},1000).animate({top:"-=20px"}); 

      } 

      window.setInterval(function(){ 
       move() 
      }, 1000); 
     }) 
    </script> 

校验,那么您的控制台,

+0

我没有看到使用匿名函数调用已定义函数的重点。 –

2

看来,你甚至不需要一个setTimeout()可言。

假设你想让yoru动画循环播放并重复播放,正确的方法是使用.animate()的完成回调,而不是使用setTimeout()。你可以这样做:

$(document).ready(function(){ 

    function move(){ 
     $("#block").animate({left:"+=50px" },1000) 
        .animate({top:"+=50px"},1000) 
        .animate({left:"-=20px"},1000) 
        .animate({top:"-=20px"}, 1000, move); 
    } 
    // call it the first time 
    move(); 
}); 

jQuery将自动为您排序四个动画。

你想知道的是当最后一个完成时,你可以再开始整个事情。您可以使用最后的.animate()操作中的完成功能,让它再次调用move()。由于此回调称为异步,堆栈上没有堆栈或递归堆栈,因此可以愉快地永远运行。


通过解释,你setTimeout()没有工作,因为当你传递一个字符串作为第一个参数setTimeout(),则该字符串在全球范围内评估,你不必在一个move()功能全球范围,因此它没有被发现,也没有被执行。如果传递一个简单的Javascript函数参考(如setTimeout(move, 1000)),则函数引用在当前作用域中计算(即使在setTimeout调用之前),并且该函数引用已正确传递。你应该几乎不会传递一个字符串到setTimeout()。这只是一个坏习惯,应该几乎总是避免并总是可以避免。但是,唉,看来你在这里甚至不需要setTimeout()


如果你想四个动画对方后序列中的一个,然后一次又一次地重复动画之前停顿1秒,你可以这样做:

$(document).ready(function(){ 

    function move(){ 
     $("#block").animate({left:"+=50px" },1000) 
        .animate({top:"+=50px"},1000) 
        .animate({left:"-=20px"},1000) 
        .animate({top:"-=20px"}, 1000, function() { 
         setTimeout(move, 1000); 
        }); 
    } 
    // call it the first time 
    move(); 
}); 

在这里,一个匿名函数作为完成回调传递给最后一个动画。在该完成功能中,将运行一个setTimeout(),它将在1000毫秒内再次调用move

P.S.我注意到你的动画不是对称的,所以它不会返回到它开始的相同位置,因此每次运行它时,对象都会反复向右移动30像素,向下移动30像素。我不确定这是否是你的意图。

+0

谢谢!现在不再混淆了,你的解释非常清楚。 –