Run setTimeout only when tab is active

前端 未结 6 1922
庸人自扰
庸人自扰 2020-11-29 20:57

Is there a way to stop setTimeout(\"myfunction()\",10000); from counting up when the page isn\'t active. For instance,

  1. A user arrives at a \"some
相关标签:
6条回答
  • 2020-11-29 21:38

    What you'd have to do is set up a mechanism to set timeouts at small intervals, keeping track of total elapsed time. You'd also track "mouseenter" and "mouseleave" on the whole page (the <body> or something). When the short-term timeouts expire, they can check the window state (in or out) and not restart the process when the window is not in focus. The "mouseenter" handler would start all paused timers.

    edit — @Šime Vidas has posted an excellent example.

    0 讨论(0)
  • 2020-11-29 21:43

    Great answer by Šime Vidas, it helped me with my own coding. For completeness sake I made an example for if you want to use setTimeout instead of setInterval:

    (function() {
    
        function myFunction() {
            if(window.blurred) {
                setTimeout(myFunction, 100);
                return;
            }
    
            // What you normally want to happen
    
            setTimeout(myFunction, 10000);
        };
        setTimeout(myFunction, 10000);
    
        window.onblur = function() {window.blurred = true;};
        window.onfocus = function() {window.blurred = false;};
    
    })();
    

    You'll see that the window blurred check has a shorter time set than normal, so you can set this depending on how soon you require the rest of the function to be run when the window regains focus.

    0 讨论(0)
  • 2020-11-29 21:43

    You can do something like:

    $([window, document]).blur(function() {
      // Clear timeout here
    }).focus(function() {
      // start timeout back up here
    });
    

    Window is for IE, document is for the rest of the browser world.

    0 讨论(0)
  • 2020-11-29 21:45

    I use almost the same approach as Šime Vidas in my slider but my code is based on document.visibilityState for page visibility checking:

    var interval = 4000;
    
    function slideshow() {
      // slideshow code
    };
    
    $(document).ready(function() {
    
    var switchInterval;
    
    function intervalHandler() {
      switchInterval = setInterval(function() {
        if (document.visibilityState === "visible") {
          slideshow();
        } else {
          return;
        }
      }, interval);
    }
    
    intervalHandler();
    
    });
    
    • About Page Visibility API: https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
    0 讨论(0)
  • 2020-11-29 21:48
    (function() {
      var time = 10000,
          delta = 100,
          tid;
    
      tid = setInterval(function() {
        if ( document.hidden ) { return; }    
        time -= delta;
        if ( time <= 0 ) {
          clearInterval(tid);
          myFunction(); // time passed - do your work
        }        
      }, delta);
    })();
    

    Live demo: https://jsbin.com/xaxodaw/quiet


    Changelog:

    • June 9, 2019: I’ve switched to using document.hidden to detect when the page is not visible.
    0 讨论(0)
  • 2020-11-29 21:59

    I've finally implemented a variation of @Šime Vidas' answer, because the interval was still running if I opened another program and the browser window was not visible, but the page executing the interval was the active browser tab. So, I've modified the condition to document.hidden || !document.hasFocus(). This way, if the document is hidden or the document doesn't have the focus, the interval function just returns.

    (function() {
      var time = 10000,
          delta = 100,
          tid;
    
      tid = setInterval(function() {
        if ( document.hidden || !document.hasFocus() ) { return; }    
        time -= delta;
        if ( time <= 0 ) {
          clearInterval(tid);
          myFunction(); // time passed - do your work
        }        
      }, delta);
    })();
    
    0 讨论(0)
提交回复
热议问题