setTimeout可以通过多个选项卡加快速度

问题描述

| 我遇到了与此类似的setTimeout问题。但是该解决方案对我没有帮助,因为我无法在文件中使用php。 我的网站上有一个滑块,其中包含每8秒移动一次的图像列表。但是,当我在浏览器中打开几个选项卡然后再次切换回时,它变得很疯狂。 滑块会立即连续移动图像,而不会延迟8秒。 我只在Chrome和最新的Firefox中看到它。 **编辑:我用console.log()检查过,并且setTimeout在clearTimeout之前和之后返回相同的数字。不知道为什么。也许这也与它有关? ** 编辑2:我添加了一个小提琴:http://jsfiddle.net/Rembrand/qHGAq/8/ 该代码如下所示:
spotlight: {
    i: 0,timeOutSpotlight: null,init: function()
   {
       $(\'#spotlight .controls a\').click(function(e) {

           // do stuff here to count and move images

           // Don\'t follow the link
           e.preventDefault();

           // Clear timeout
           clearTimeout(spotlight.timeOutSpotlight);

           // Some stuff here to calculate next item

           // Call next spotlight in 8 seconds
           spotlight.timeOutSpotlight = setTimeout(function () {
                spotlight.animate(spotlight.i);
            },8000);
       });

       // Select first item
       $(\'#spotlight .controls a.next:first\').trigger(\'click\');
   },animate: function(i)
   {
       $(\'#spotlight .controls li:eq(\' + (spotlight.i) + \') a.next\').trigger(\'click\');
   }
}
    

解决方法

从jQuery文档中:   由于requestAnimationFrame()的性质,您永远不应该   使用setInterval或setTimeout循环将动画排入队列。为了   保留CPU资源,支持requestAnimationFrame的浏览器   当不显示窗口/选项卡时,将不会更新动画。如果   您继续通过setInterval或setTimeout将动画排入队列,同时   动画已暂停,所有排队的动画将开始播放   当窗口/标签重新获得焦点时。为避免此潜在问题,   在循环中使用您上一个动画的回调,或附加一个   对元素.queue()的函数设置超时时间以开始下一个   动画。     ,我终于找到了答案,这根本不是我所期望的。 罪魁祸首似乎是jQuery的.animate(),我用它在滑块中移动图像。 我以此计算并移动图像位置:
$(\'.spotlight-inner\')
    .animate(
        { left: scrollToVal },{duration: \'slow\'}
    )
 ;
现在的问题似乎是在某些浏览器中,当您切换到新的选项卡并返回时,jQuery的.animate()保存动画并立即将其全部触发。因此,我添加了一个过滤器以防止排队。该解决方案来自CSS-Tricks.com:
$(\'.spotlight-inner\')
    .filter(\':not(:animated)\')
    .animate(
        { left: scrollToVal },{duration: \'slow\'}
    )
;
当您返回时看到的第一张幻灯片可能有点跳动,但它比以前的超高速旋转木马要好。 在这里摆弄完整的代码     ,使用jquery animate queue属性有一种更简单的方法:
$(this).animate({
    left: \'+=100\'
},{duration:500,queue:false});
    ,我不知道这是否对您有帮助,但是幻灯片显示对我有帮助。我所做的就是每次我调用一个由于setTimeout而应在固定间隔内发生的动画时,我都调用clearQueue()来清除任何其他已设置为发生的动画。然后我会调用动画。这样一来,当您返回该标签时,就不会将所有这些动画排入队列,这简直太疯狂了。最多只能设置一个。 所以像这样:
       spotlight.timeOutSpotlight = setTimeout(function () {
            spotlight.clearQueue(); // get rid of other instances of the animation
            spotlight.animate(spotlight.i);
        },8000);
它可能并非在所有情况下都有效(取决于时间),但我希望对您有所帮助!     ,您还必须认为您使用clearTimeout。 当您调用setTimeout函数时,它返回一个ID,您可以将此ID保存在一个变量中,例如
timeoutID = setTimeout(function () {
                spotlight.animate(spotlight.i);
            },8000);
在设置新超时之前,您可以调用如下函数
clearTimeout(timeoutID)
    ,我怀疑浏览器会将输入事件排入\'click \'之类,但仅在事件发生的选项卡实际上具有焦点时才触发它们。 也许您应该尝试直接调用点击回调,而不要使用
trigger(\'click\')
。 像这样:
spotlight: {
    i: 0,timeOutSpotlight: null,clickFunc: function(element) {

       // do stuff here to count and move images

       // Clear timeout
       clearTimeout(spotlight.timeOutSpotlight);

       // Some stuff here to calculate next item

       // Call next spotlight in 8 seconds
       spotlight.timeOutSpotlight = setTimeout(function () {
            spotlight.animate(spotlight.i);
       },8000);
   },init: function()
   {

       $(\'#spotlight .controls a\').click(function (e) {

           // Don\'t follow the link
           e.preventDefault();

           spotlight.clickFunc(this);
       });

       // Select first item
       spotlight.clickFunc($(\'#spotlight .controls a.next:first\'));
   },animate: function(i)
   {
       var element = $(\'#spotlight .controls li:eq(\'+spotlight.i+\') a.next\');
       spotlight.clickFunc(element);
   }
}
    ,您正在运行什么版本的jQuery?显然,此问题在1.6.3版中已“修复”,他们还原了导致这种情况发生的更改。这里和这里的讨论。 尽管将来可能必须解决此问题,但似乎我们暂时无法解决。     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...