Chrome 动画超时问题

发布于 2024-11-29 14:42:21 字数 858 浏览 1 评论 0原文

我用 jQuery 和 autplay 编写了一个简单的滑块。如果启用自动播放,则会设置指向函数的 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();

I've written a simple Slider in jQuery with autplay. If autoplay is enabled a setTimeout is set that points to a function. This function then has a recursive setTimeout to itself.

All works well, except in Chrome. After I've changed a tab, wait for a while and return, the slider is freaking out. It looks like there are multiple instances of the timeout active... but that cannot be the case since I appoint the timeout to the same variable.

Some relevant code:

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();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

仲春光 2024-12-06 14:42:21

不,重置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();

No, resetting the value of timer will not cancel the current timer. For that you need to clearTimeout. All timer holds is a numeric reference to the timer, not a closure or anything of that nature.

Assuming you have a good condition to start setTimer(), your code should look more like this:

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();
樱桃奶球 2024-12-06 14:42:21

setTimeout的返回是一个索引号,用于定时器的内部识别,而不是实际的定时器本身。因此,您只是重写了指向计时器的内容,而不是在再次创建计时器时删除正在运行的计时器。

为了节省计算能力,Chrome 引擎冻结了后台选项卡中运行的大多数 JavaScript,然后当它重新获得焦点时似乎会尝试“赶上”。但不确定修复方法是什么。绝对使用clearTimeout或更好的方法,但使用Timer对象来尝试将其捕获为重复操作。

the return of the setTimeout is an index number that is used for internal recognition of the timers, not the actual timer itself. therefore you are only writing over the thing that is pointing to a timer, not removing the timer that is running when you make the timer again.

To save computing power, the chrome engine freezes most javascript running in background tabs, and then seems to try and "catch up" when it gets back in focus. Not sure what the fix would be for this though. definitely use the clearTimeout or better yet use a Timer object to try and catch this as a repetetive action.

骄傲 2024-12-06 14:42:21

我尝试找到一个小修复。您可以尝试将其添加到您的代码中

var timer;

...

$(window).blur(function() {
    clearTimeout(timer);
}).focus(function() {
    timer= setInterval(autoplay, interval*1000);
});

希望这可以有所帮助。

I've tried found a small fix. You can try to add this to your code

var timer;

...

$(window).blur(function() {
    clearTimeout(timer);
}).focus(function() {
    timer= setInterval(autoplay, interval*1000);
});

Hope this can help.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文