setInterval在Chrome上无法正常运行

我有一个自定义幻灯片对象来执行名称在网站上指示的常用内容。 除非我在Chrome中切换标签并返回网站标签,否则一切正常。 当发生这种情况时,幻灯片放映并开始淡化图像而忽​​略给定的setInterval间隔。 找不到与此相关的任何问题,所以我想至少知道代码是否存在问题或软件问题。

这是代码(与jQuery一起使用):

 $(function() { // slideshow var slideshow = { id : false, current : 0, count : 0, interval : false, init : function(data) { if (!data) return false; $.each(data, $.proxy( function(index, value) { this[index] = data[index]; }, this) ); this.count = this.images.length; for (x=1;x<=this.count;x++) $('#slider ul.nav').append('
  • '); $('#slider ul.nav li').live('click', function() { slideshow.click(this); }); $('#slider ul.nav li:eq(0)').addClass('on'); $('#slider ul.nav').css('width', (15*this.count)+'px'); return true; }, start : function () { slideshow.id = setInterval(function() { slideshow.action(); }, slideshow.options.interval); }, stop : function() { clearInterval(slideshow.id); }, action : function() { slideshow.current < (slideshow.count-1) ? slideshow.current++ : slideshow.current = 0; $('#slider img').fadeOut('normal', function() { $('#slider img').attr('src', slideshow.images[slideshow.current].url); $('#slider ul.nav li').removeClass('on'); $('#slider ul.nav li:eq('+slideshow.current+')').addClass('on'); $('#slider div.title').html(slideshow.images[slideshow.current].title); $('#slider div.description').html(slideshow.images[slideshow.current].description); $('#slider a.more').attr('href', slideshow.images[slideshow.current].target); }).fadeIn('normal'); return true; }, click : function(o) { slideshow.stop(); var index = $('#slider ul.nav li').index(o); slideshow.current = index; $('#slider img').fadeOut('normal', function() { $('#slider img').attr('src', slideshow.images[index].url); $('#slider ul.nav li').removeClass('on'); $(o).addClass('on'); $('#slider div.title').html(slideshow.images[index].title); $('#slider div.description').html(slideshow.images[index].description); $('#slider a.more').attr('href', slideshow.images[index].target); }).fadeIn('normal'); slideshow.start(); return true; }, }; slideshow.init(slider); slideshow.start(); });

    我倾向于使用setInterval()重复使用setTimeout() – setInterval()会出现很多问题,你不知道浏览器有多忙以及间隔是否真实。

    浏览器不会完全遵守您选择的超时或间隔。 这主要是为了安全; 防止大量事件搞乱浏览器正常运行的能力。 Chrome更适合更准确地表达计时器,例如,当选项卡处于后台时,它仍会显着降低计时器的速度( 请参阅此答案 )。

    如果你在现有的slideshow.action()调用期间设置了一个带有setTimeout的新计时器,那么当你的浏览器无法跟上时,你就不会让事件排队,但是当浏览器是能够这样做。

    您仍然可以使用计时器ID停止计时器,该ID将经常更改。

    当选项卡在后台时,Chrome(以及显然也是最新版本的Firefox)会降低setInterval的速度,以提高前景性能。 当背景页面中有快速运行的定时器驱动的动画时,这可能是最重要的。 当页面回到前台时,它“尝试”赶上并运行一堆setInterval调用,比通常运行的速度快得多。

    解决方法是:

    1. 延长setInterval的时间,以便Chrome不会弄乱它(你必须查看那个时间)。
    2. 当页面进入后台时停止间隔计时器(无论如何都不需要运行幻灯片) – 然后在页面到达前台时再次启动它。
    3. 使用重复的setTimeout而不是setInterval与某种类型的重复setTimeout,如下所示:

    码:

     function nextSlide() { // show next slide now // set timer for the slide after this one setTimeout(function() { nextSlide(); // repeat }, xxx) } 

    这里的post类似。

    最有可能的是,您不应期望setInterval准确无误。 如果我是你,我会通过将之前的间隔时间与当前的间隔时间进行比较来检查间隔是否正确。 这应该使代码更健壮。

    铬有类似的问题

    正如我已经解决了这个问题。 在开始时,记下mktime变量,然后简单地从当前时间中减去。 例:

     var values = {}; function mktime(){ var date = new Date(); return Math.floor(date.getTime()/1000); } function getTime(string){ var splitContent = string.split(/\:/g); var hours = parseInt(splitContent[0]) * 60 * 60; var minutes = parseInt(splitContent[1]) * 60; var seconds = parseInt(splitContent[2]); return hours + minutes + seconds; } function startTimer(time){ values.startMkTime = mktime(); values.startTime = getTime(time); setInterval(process(),1000); } function process(){ values.currentTime = (mktime() - values.startMkTime) + o.values.startTime;//new code }