【问题标题】:Jquery setInterval too fast when coming from another tab来自另一个选项卡时,Jquery setInterval 太快了
【发布时间】:2011-10-07 21:37:30
【问题描述】:

我有一个使用 jquery 的 setIntervall() 函数不断滑动图像的网站。

当在 Chrome 13 中调用页面并切换到另一个选项卡以在几秒钟后返回时,图像滑动发生得更快,好像它试图跟上它没有切换到另一个选项卡的位置.

我该如何解决这个问题?

$(window).load(function() { 
    setInterval(nextSlide, 3500);
});

function nextSlide(){   
    offset += delta;
    $("#slideContent").animate({left: -1 * offset}, 1000);
}

【问题讨论】:

  • 你为什么选择 jfriend00 的解决方案在不活动时关闭计时器,而不是 nitek 的解决方案 .stop() 队列?

标签: javascript jquery google-chrome setinterval


【解决方案1】:

一开始我想为所有的错误道歉——我的英语并不完美。

你的问题的解决方法可能很简单:

$(window).load(function() { 
    setInterval(nextSlide, 3500);
});

function nextSlide(){   
    offset += delta;
    $("#slideContent").stop(true,true).animate({left: -1 * offset}, 1000);
}

不活动的浏览器选项卡会缓冲一些 setInterval 或 setTimeout 函数。 stop(true,true) - 将停止所有缓冲事件并只执行最后一个动画。 这个问题也会出现在 Firefox > 5.0 - 阅读这篇文章:Firefox 5 - changes

window.setTimeout() 方法现在限制发送不超过一个 在非活动选项卡中每秒超时。此外,它现在夹住嵌套 超时到 HTML5 规范允许的最小值:4 毫秒(而不是它用来钳制的 10 毫秒)。

您可以在此处阅读 animate 的工作原理 - 它会多次触发 setInterval 函数。 How animate really works in jQuery

【讨论】:

  • 英语是我的母语,我的也不完美!这里的问题是你的代码比你的英语有多好。不要太担心它。 :-)
【解决方案2】:

当标签页在后台时,最新版本的 Chrome 显然会减慢 setInterval 的操作,然后当您将该页向前移动时,它会试图赶上。

在 Chromium 博客上,谷歌表示:

在即将发布的 Chrome 11 版本中,我们计划减少 CPU 消耗,即使对于使用 setTimeout 和 setInterval 的页面也是如此。对于后台选项卡,我们打算每秒运行每个独立计时器不超过一次。此更改已在 Chrome 开发通道和金丝雀版本中实现。

您的间隔是 3.5 秒,但动画本身可能使用更短的计时器。

可能的解决方法:

  • 当窗口不可见时停止计时器/动画。当窗口可见时重新启动计时器/动画。
  • 使用 setTimeout 代替 setInterval,然后在每次触发时重置 setTimeout 以创建您自己的重复间隔 - 尽管在您的情况下,问题可能是 jQuery 对计时器的使用 - 我不知道。
  • 放慢你的定时器,这样它们就不会与此发生冲突(同样可能是在 jQuery 内部,而不是你自己的定时器)。

最好的选择可能是弄清楚何时停止然后重新启动动画。

这里有类似的问题:Chrome: timeouts/interval suspended in background tabs?

仅供参考,Chrome 有新的实验性 API 用于检测页面可见性正是出于这个原因。你可以在这里阅读:http://code.google.com/chrome/whitepapers/pagevisibility.html。当您的页面可见但没有焦点时,它有助于解决问题。

【讨论】:

  • 我对“失去焦点技术”感到疑惑的一件事是,当网页在一个单独的窗口中并且完全可见时,动画不会运行,但不是有焦点的窗口.如果用户使用选项卡,则不会发生这种情况,但如果他们在足够大的屏幕上打开多个浏览器窗口以使这些窗口都可见,则可能发生这种情况。您真正想知道的是它是否可见。
  • 我在上面的回答中添加了对 Chrome 页面可见性 API 的引用。
【解决方案3】:

您好,您使用的是 Jquery 1.6 吗?

这可能是因为 1.6 使用 requestAnimationFrame 来制作动画。 您可能需要查看此页面以替换 setInterval、clearInterval

http://blog.blenderbox.com/2011/06/24/jquery-1-6-1-and-setinterval/

代码: https://gist.github.com/1002116 [编辑:更新源,edit2:由于 firefox 错误,目前无法与 firefox 一起使用。 -- 我已经降级到 JQuery 1.5]

来自博主:

然后,在你调用 setInterval(func, poll) 的地方,你现在调用 请求间隔(函数,轮询)。在你调用 clearInterval(interval) 的地方, 你现在调用 clearRequestInterval(interval);

【讨论】:

    【解决方案4】:

    您是否尝试过完全不使用setIntervalsetTimeout,而只使用animate 函数的complete 函数来开始下一张幻灯片? delay 函数设置为 2500(即从 setInterval 的 3500 中减去动画的 1000)。我还没有在 Chrome 上尝试过这个,所以请告诉我它是否有效。

    var slider = function(n){
        $("#slideContent").delay(2500).animate({left: -1 * n * delta},
                                               1000,
                                               function(){slider(n+1)}
                                              );
    };
    slider(1);
    

    【讨论】:

    • 感谢您的回答。我在切换到另一个选项卡时关闭了计时器,但明天我会测试你的代码,让你知道它是否有效。
    • Christian,谢谢你 - 很高兴知道你有解决方案。问候
    • 感谢您的信息。大多数人使用 setTimeout/setInterval 进行重复动画,但我发现使用“delay()”以及“animate”的回调机制或其他动画函数通常也可以正常工作,在某些情况下效果更好。问候
    【解决方案5】:

    试试setInterval()它可以工作

    <script type="text/javascript" src="js/jquery-1.5.js"></script>
            <script type="text/javascript">
                var i=1;
                $(document).ready(function(){
                    slideShow();
                    $("#next").click(function(){
                        slideShow();
                    });
                });
                function slideShow(){
                    if(i<3){
                        $("#slide-container").animate({ left:"+=35px" }, {  duration:500})
                        $("#slide-container").animate({ left:"-=735px" }, {  duration:250})
                        i++;
                    }
                    else {
                        $("#slide-container").animate({ left:"+=1400px" }, {  duration:1000})
                        i=1;
                    }
                    setTimeout('slideShow()',2000);
                }
        </script>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-06
      • 2014-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多