Run setTimeout only when tab is active

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 page" and stays there for 2000ms
  2. User goes to another tab, leaves "some page" open.
  3. myfunction() doesn't fire until they've come back for another 8000ms.

Solution 1:

(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.

Solution 2:

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.

Solution 3:

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.