我在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();
答案 0 :(得分:0)
不,重置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();
答案 1 :(得分:0)
setTimeout的返回是一个索引号,用于内部识别定时器,而不是实际的定时器本身。因此,你只是在写一个指向计时器的东西,而不是删除再次制作计时器时正在运行的计时器。
为了节省计算能力,Chrome引擎会冻结在后台标签中运行的大多数javascript,然后当它重新聚焦时,似乎会尝试“赶上”。虽然不确定这个解决方案是什么。肯定使用clearTimeout或更好的方法,然后使用Timer对象尝试捕获它作为重复动作。
答案 2 :(得分:0)
我试过找到一个小修复。您可以尝试将其添加到代码中
var timer;
...
$(window).blur(function() {
clearTimeout(timer);
}).focus(function() {
timer= setInterval(autoplay, interval*1000);
});
希望这可以提供帮助。