Chrome timeout problem with animation

余生颓废 提交于 2019-12-12 04:28:49

问题


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

回答1:


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



回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/7064237/chrome-timeout-problem-with-animation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!