【问题标题】:How can I pause a recursive setTimeout while I change tab(focus)如何在更改选项卡(焦点)时暂停递归 setTimeout
【发布时间】:2019-03-08 19:28:53
【问题描述】:

我的代码:

  let isBlack = true;
  function animate() {
    $(".someDiv").animate({
      backgroundColor: isBlack ? "transparent" : 'black'
    }, 20);
    isBlack = !isBlack;
  }

  const delay = ms => new Promise(res => setTimeout(res, ms));
  async function animateAndWait(msArr) {
    for (let i = 0; i < msArr.length; i++) {
      animate();
      await delay(msArr[i]);
    }
  }

  flashFunction();

  async function flashFunction() {
    await animateAndWait([300, 50]);
    if (myRandomNumberBetween(1, 100) <= 10) {
      return delay(3000)
        .then(flashFunction);
    }
    await animateAndWait([300, 400]);
      delay(3000)
        .then(flashFunction);
  }

它使 div 以约 3 秒的间隔闪烁几次。 当我切换标签时出现我的问题。当我在另一个选项卡上时,该浏览器会暂停计时器,然后,当我返回此选项卡时,它会闪烁(快速)在后台丢失的所有闪烁。

我想在后台以某种方式暂停计时器或清除间隔。有些人问过同样的问题,但我无法在此处包含对他们有帮助的答案。或者也许我只是不知道怎么做。这可能超出我的想象,但如果有人有时间,我会很感激他们的帮助。

这里有一些来自有类似问题的人的链接:

recursive setTimeout() pause on background

Animations pause when browser tab is not visible

【问题讨论】:

    标签: javascript animation async-await settimeout


    【解决方案1】:

    您可以使用window.onblur / window.onfocus事件销毁/重新生成TIMEOUT时标签丢失/恢复焦点。

    let myTimeout;
    
    window.onfocus = function() {
      console.log('focus')
      clearTimeout(myTimeout);
      myAction();
    };
    
    window.onblur = function(){
       console.log('blur')
       clearTimeout(myTimeout);
    };
    
    function myAction(){
      /* 
         your code ...
      */
      console.log('new cycle')
      myTimeout = setTimeout( myAction, 1000 );
    }
    
    myAction();
    

    如果您正在寻找能够暂停/恢复的计时器,请查看tiny library

    【讨论】:

      【解决方案2】:

      如果像我这样的初学者想知道我如何将我的代码与 colxi 对我的问题的回答结合起来,那就是:

         let myTimeout;
         let isBlack = true;
      
      
          window.onfocus = function() {
            console.log('focus')
            clearTimeout(myTimeout);
            myAction();
          };
      
          window.onblur = function(){
            console.log('blur')
            clearTimeout(myTimeout);
          };
      
          function animate() {
            $(".playerInfoCoatTwo").animate({
              backgroundColor: isBlack ? "transparent" : 'black'
            }, 20);
            isBlack = !isBlack;
          }
      
          function myAction(){
      
            const delay = ms => new Promise(res => myTimeout = setTimeout(res, ms)); // some changes here
      
            async function animateAndWait(msArr) {
              for (let i = 0; i < msArr.length; i++) {
                animate();
                await delay(msArr[i]);
              }
            }
      
            flashFunction();
      
            async function flashFunction() {
              await animateAndWait([300, 50]);
              if (myRandomNumberBetween(1, 100) <= 10) {
                return delay(3000)
                  .then(flashFunction);
              }
              await animateAndWait([300, 400]);
                delay(3000)
                  .then(flashFunction);
            }
            console.log('new cycle') 
          }
      
          myAction();
      

      但是我不知道它是否是最优的。尽管如此,它仍然有效!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-11-25
        • 1970-01-01
        • 2019-10-29
        • 2014-01-02
        • 1970-01-01
        • 1970-01-01
        • 2019-10-01
        相关资源
        最近更新 更多