Chrome动画的超时问题

我在jQuery中用autplay编写了一个简单的Slider。 如果启用了自动播放,则设置指向函数的setTimeout。 然后,此函数对其自身具有递归setTimeout。

一切正常,除了Chrome。 在我更换了标签后,等待一段时间然后返回,滑块就吓坏了。 看起来有多个超时活动实例……但是由于我将超时指定给同一个变量,所以情况并非如此。

一些相关代码:

var timer; function autoplay() { currentPosition++; if(currentPosition == numberOfSlides) { // last slide currentPosition = 0; } manageNavigation(currentPosition); // Hide / show controls manageControls(currentPosition); // animate the slides slideshowAnimate(); // set timer if(autoplay_enable) { //clearTimeout(timer); timer = setTimeout(function() { autoplay() }, interval*1000) } } function setTimer() { if(autoplay_enable) { timer = setTimeout(function() { autoplay() }, interval*1000) } } setTimer(); 

不,重置timer的值不会取消当前计时器。 为此你需要clearTimeout 。 所有计时器保持都是计时器的数字引用,而不是闭包或任何此类性质。

假设您有一个良好的条件来启动setTimer() ,您的代码应该看起来更像这样:

 var timer; function autoplay() { clearTimeout(timer); //! New code. currentPosition++; if(currentPosition == numberOfSlides) { // last slide currentPosition = 0; } manageNavigation(currentPosition); // Hide / show controls manageControls(currentPosition); // animate the slides slideshowAnimate(); // set timer setTimer(); //! Switched from having multiple startup locations. } function setTimer() { if(autoplay_enable) { timer = setTimeout(autoplay, interval*1000); //! Removed unnecessary closure. } } setTimer(); 

setTimeout的返回是一个索引号,用于内部识别定时器,而不是实际的定时器本身。 因此,您只是在写一个指向计时器的东西,而不是删除再次制作计时器时正在运行的计时器。

为了节省计算能力,chrome引擎冻结了在后台标签中运行的大多数javascript,然后在重新聚焦时似乎尝试“赶上”。 不知道解决方案是什么。 肯定使用clearTimeout或者更好,但是使用Timer对象尝试将其作为重复动作捕获。

我试过找到一个小修复。 您可以尝试将其添加到您的代码中

 var timer; 

 $(window).blur(function() { clearTimeout(timer); }).focus(function() { timer= setInterval(autoplay, interval*1000); }); 

希望这可以提供帮助。