Detect If Browser Tab Has Focus

Is there a reliable cross-browser way to detect that a tab has focus.

The scenario is that we have an application that polls regularly for stock prices, and if the page doesn't have focus we could stop the polling and save everyone the traffic noise, especially as people are fans of opening several tabs with different portfolios.

Is window.onblur and window.onfocus an option for this?


Yes, window.onfocus and window.onblur should work for your scenario:

http://www.thefutureoftheweb.com/blog/detect-browser-window-focus


Important Edit: This answer is outdated. Since writing it, the Visibility API (mdn, example, spec) has been introduced. It is the better way to solve this problem.


var focused = true;

window.onfocus = function() {
    focused = true;
};
window.onblur = function() {
    focused = false;
};

AFAIK, focus and blur are all supported on...everything. (see http://www.quirksmode.org/dom/events/index.html )


Surprising to see nobody mentioned document.hasFocus

if (document.hasFocus()) console.log('Tab is active')

MDN has more information.


While searching about this problem, I found a recommendation that Page Visibility API should be used. Most modern browsers support this API according to Can I Use: http://caniuse.com/#feat=pagevisibility.

Here's a working example (derived from this snippet):

$(document).ready(function() {
  var hidden, visibilityState, visibilityChange;

  if (typeof document.hidden !== "undefined") {
    hidden = "hidden", visibilityChange = "visibilitychange", visibilityState = "visibilityState";
  } else if (typeof document.msHidden !== "undefined") {
    hidden = "msHidden", visibilityChange = "msvisibilitychange", visibilityState = "msVisibilityState";
  }

  var document_hidden = document[hidden];

  document.addEventListener(visibilityChange, function() {
    if(document_hidden != document[hidden]) {
      if(document[hidden]) {
        // Document hidden
      } else {
        // Document shown
      }

      document_hidden = document[hidden];
    }
  });
});

Update: The example above used to have prefixed properties for Gecko and WebKit browsers, but I removed that implementation because these browsers have been offering Page Visibility API without a prefix for a while now. I kept Microsoft specific prefix in order to stay compatible with IE10.