【问题标题】:Chrome timeout problem with animationChrome 动画超时问题
【发布时间】:2011-08-15 11:08:01
【问题描述】:

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

【问题讨论】:

    标签: jquery google-chrome settimeout


    【解决方案1】:

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

    【讨论】:

    • 我认为这段代码只是在语义上不同。将我的原始代码更改为这样的内容会导致 Chrome 在 tabchange 后失败并在稍后阶段返回标签。
    • 真正需要添加的唯一位是 clearTimeout。听起来您的启动状态还有其他问题。我希望所有这些都是全局的还是包含在一个启动关闭中?
    【解决方案2】:

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

    为了节省计算能力,chrome 引擎冻结了大多数在后台选项卡中运行的 javascript,然后似乎在重新获得焦点时尝试“赶上”。不知道解决这个问题的方法是什么。绝对使用 clearTimeout 或更好,但使用 Timer 对象尝试将其作为重复操作。

    【讨论】:

    • 好的,所以这基本上是 Chrome 的问题? “追赶”是否意味着最终它会以应有的方式制作动画?
    • 这里的开发频道上有一些 cmets:groups.google.com/a/chromium.org/group/chromium-dev/… 这可能很有趣,但每次调用的节流似乎是 1 秒,这应该没问题。可能是动画过渡杀死了它,尝试为动画锁定输入布尔值或剥离动画进行测试。
    【解决方案3】:

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

    var timer;
    

    ...

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

    希望这能有所帮助。

    【讨论】:

      猜你喜欢
      • 2014-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-10
      • 2016-07-24
      • 1970-01-01
      • 1970-01-01
      • 2011-12-09
      相关资源
      最近更新 更多