Using the new Page visibility API in your apps

One of the features lacking in the current browser api is that of determining whether the web page is currently visible to the user or is hidden (either in another tab or window).

The new Page Visibility API allows you to do just that – determine whether your web page is visible to the user, is hidden in a background tab or window, or is prerendering. It allows the developer to use the page visibility state in JavaScript logic to make the user experience more friendly; for example, by stopping video, animation or slideshow playback whenever the user switches to another browser tab or window, and resuming whenever the user switches back. Also if your page is doing some ajax processing periodically, which consumes precious system resources, we can pause it when the page is not in focus. Other use can be in analytics, checking how long the page had been in actual user focus, rather then as a hidden tab or window.

Check the below demo page to see how this works. The demo was tested in Safari, Opera 11.10, Chrome and Firefox.

Notice how the video pauses whenever the page is hidden. Also check the title of the page as it switches state.

The api is quite simple in its design – whenever a web page visibility changes, the ‘visibilitychange’ event is fired. This event can then be registered using the addEventListener method.

Currently the Page Visibility API supports three visibility states:
‘visible’ : user has opened the page and is working within it.
‘hidden’ : user has switched to another tab or minimized browser window.
‘prerender’ : browser is just prerendering a page.

However the problem with the current api implementation is that different browsers have implemented the api specification a little differntly, which can make working with them a little tedious. So one option is to use a wrapper which hides the various browser differences. Visibility.js is one such wrapper which eases the usage of the api by hiding vendor-specific property prefixes and adding some high-level functions.

Below is the complete source for the above demo page. I’d not go into further details, as the respective pages have all the detailed documentation.

<!DOCTYPE html>
    <meta charset='UTF-8'>
    <script src="lib/visibility.fallback.js"></script>
    <script src="lib/visibility.js"></script>
    <script src="swfobject.js"></script>
<h1>Visibility.js test</h1>
<p>Page Visibility API <strong id="support"></strong>.</p>
<p>Switch browser tabs or window.</p>
<div id="ytapiplayer">
You need Flash player 8+ and JavaScript enabled to view this video.
<script type="text/javascript">
function onYouTubePlayerReady(playerId) {
  ytplayer = document.getElementById("myytplayer");
function play() {
    if (ytplayer) ytplayer.playVideo();
function pause() {
    if (ytplayer) ytplayer.pauseVideo();
var params = { allowScriptAccess: "always" };
var atts = { id: "myytplayer" };
swfobject.embedSWF("" +
                   "ytapiplayer", "425", "356", "8", 
                   null, null, params, atts);
/* Make sure page visibility api is supported */                   
var support = document.getElementById('support');
if ( Visibility.isSupported() ) {
    support.innerHTML = 'is supported';
} else {
    support.innerHTML = 'isn’t supported';
document.title = Visibility.state();
/* Pause/Play video when the page changes state */
Visibility.change(function (e, state) {
    /* Also change the page title on state change */
    document.title = state;
    if(state == "visible")

3 Responses

  1. Shane says:

    Love this, but it doesn’t seem to be working in IE. Is IE supposed to be supported?

  2. IE will support Page Visibility API at 10 version.

  3. Your code is not correctly. You need to check `Visibility.hidden()` instead of `state == “visible”`, because later another states may be added to API.