jQuery / JavaScript:当tab变为非活动状态时,我的递归setTimeout函数会加速

在我正在构建的jQuery幻灯片插件中,我有一个奇怪的小难题。

这没什么特别的,我迄今为止编写的代码工作得很好但是我注意到当我离开网站运行并切换到新选项卡并继续在另一个选项卡中浏览网页(在我的情况下Chrome for Mac)时我回到我的网站, setTimeout调用似乎加速了,而不是等待计时器完成火灾事件,它不断发射。

这是我的(简化)代码:

 var timer; var counter; var slides; // collection of all targeted slides. // animate to the next slide function nextSlide() { // stop timer methods.stopTimer(); // increase counter counter++; if ( counter > slides.length-1 ) { counter = 0; } // if counter is greater than the amount of slides, back to the start. // inner = container to be animated // in the complete callback restart the timer. inner.animate({ 'left': '-'+slides.eq( counter ).position().left }, { duration : settings.animationSpeed, easing : 'easeInOutExpo', complete : startTimer() }); } // timer functions. function startTimer() { if ( timer === '' ) { timer = setTimeout( function() { nextSlide(); } , 3000 ); } } function stopTimer() { clearTimeout( timer ); timer = ''; } 

所以应该发生的是,在动画结束时,计时器会重新附加另一个setTimeout调用,以便它成为一个连续的幻灯片(这样就可以正常工作,直到你离开标签。

一旦你离开标签并返回带有幻灯片的标签,似乎3000 ms计时器已被缩减以立即调用,现在动画结束时,下一个计时器开始时没有任何延迟。

关于为什么会如何解决这个问题的任何想法都将非常感激。

谢谢阅读,

Jannis

某些浏览器(如Chrome)会在标签变为非活动状态时大幅减慢重复定时器,然后当标签再次激活时,它们会尝试“赶上”,以便发生相同数量的实际定时器事件。 所有我能想到的解决方法是让您在选项卡处于非活动状态时完全停止幻灯片放映,并在活动时再次启动它。

你有没有试过间隔而不是超时? 也是为了递归,只需将nextSlide()函数作为自己的回调函数调用:

 var counter = 1; // animate to the next slide function nextSlide() { // increase counter counter++; // if counter is greater than the amount of slides, back to the start. counter = ( counter > slides.length-1 ) ? 0 : counter; // inner = container to be animated // in the complete callback restart the timer. inner.animate( { 'left': '-' + slides.eq( counter ).position().left }, { duration : settings.animationSpeed, easing : 'easeInOutExpo', complete : nextSlide() }); } 

那么这只是启动和停止间隔的问题:

 var slideshow; function startSlideshow() { slideshow = setInterval(nextSlide(),3000); } function stopSlideshow() { clearInterval(slideshow); inner.stop(); }