O'Reilly

Page Visibility API

By on  

One event that's always been lacking within the document is a signal for when the user is looking at a given tab, or another tab. When does the user switch off our site to look at something else? When do they come back? The Page Visibility API allows developers to react to changes in page visibility via the visibilitychange document event. New document.hidden and document.visibilityChange properties are also available.

document.hidden

This new document property, document.hidden, returns true the page is currently not visible.

document.visibilityState

The visibilityState will either be visible (the page is the foreground tab of a non-minimized window), hidden (document is either a background tab or part of a minimized window), or prerender (the page content is being prerendered and is not visible to the user).

visibilitychange Event

Listening for changes in window visibility is as easy as:

// Adapted slightly from Sam Dutton
// Set name of hidden property and visibility change event
// since some browsers only offer vendor-prefixed support
var hidden, state, visibilityChange; 
if (typeof document.hidden !== "undefined") {
	hidden = "hidden";
	visibilityChange = "visibilitychange";
	state = "visibilityState";
} else if (typeof document.mozHidden !== "undefined") {
	hidden = "mozHidden";
	visibilityChange = "mozvisibilitychange";
	state = "mozVisibilityState";
} else if (typeof document.msHidden !== "undefined") {
	hidden = "msHidden";
	visibilityChange = "msvisibilitychange";
	state = "msVisibilityState";
} else if (typeof document.webkitHidden !== "undefined") {
	hidden = "webkitHidden";
	visibilityChange = "webkitvisibilitychange";
	state = "webkitVisibilityState";
}

// Add a listener that constantly changes the title
document.addEventListener(visibilityChange, function() {
	document.title = document[state];
}, false);

// Set the initial value
document.title = document[state];

The example above changes the document.title property during every visibility change!

Supporting visibilityChange in MooTools

MooTools doesn't support visibilityChange out of the box, so you'll need to add this bit of JavaScript:

// Set it up!
Element.NativeEvents[visibilityChange] = 2;
Element.Events[visibilityChange] = {
	base: visibilityChange,
	condition: function(event) {
		event[state] = document[state];
		event.visibilityState = document[state];
		return true;
	}
};

// Now use it!
document.addEvent(visibilityChange, function(e) {
	document.title = document[state];
});

Don't you love it when it's that easy?! This mirror the code needed to add onMessage events to the list of supported events.

So what could visibilitychange be used for? You could stop periodically refreshing content when the page is no longer visible, then pull new content when the page becomes visible again. You could pause and resume a video during visibility changes. Audio too. You could adjust your site statistics to count only time spent on site while the page is visible. There's loads you can do! So...the question is...what would you do with this?

Track.js Error Reporting

Upcoming Events

Recent Features

  • How I Stopped WordPress Comment Spam

    I love almost every part of being a tech blogger:  learning, preaching, bantering, researching.  The one part about blogging that I absolutely loathe:  dealing with SPAM comments.  For the past two years, my blog has registered 8,000+ SPAM comments per day.  PER DAY.  Bloating my database...

  • Introducing MooTools Templated

    One major problem with creating UI components with the MooTools JavaScript framework is that there isn't a great way of allowing customization of template and ease of node creation. As of today, there are two ways of creating: new Element Madness The first way to create UI-driven...

Incredible Demos

  • HTML5 Context Menus

    One of the hidden gems within the HTML5 spec is context menus. The HTML5 context menu spec allows developers to create custom context menus for given blocks within simple menu and menuitem elements. The menu information lives right within the page so...

  • Google-Style Element Fading Using MooTools or jQuery

    Google recently introduced an interesting effect to their homepage: the top left and top right navigation items don't display until you move your mouse or leave the search term box. Why? I can only speculate that they want their homepage as...

Discussion

  1. marius

    Great tip! I never heard of it. A mention: it seems that it’s not working in Opera (v.11.51)

    • This is a “cutting edge” API. Works in Chrome and Safari, and is currently available in Mozilla Aurora. I believe it’s good for IE10 as well, so Opera should implement it shortly.

  2. Nico Granelli

    This is cool, I will implement a plugin that mess with the data when the client isn’t watching. I will love to see the reports about this kind of error :)

  3. Jason

    FF 5.0.1 Fail, Safari 5.0.3 Fail, IE 9 Fail. I like the idea, but looks like it’s going to be a while before it’s useful.

  4. Alex

    Something I detected while browsing a file sharing website was that when the non-premium user changes the tab, the countdown pauses and can only continue if focused again.
    After investigating the sourced I detected that the site was using the window focus/blur events.
    Using Cheat Engine’s Speedhack on firefox though, I could bypass this protection.

    • Alex

      FileServe it is, go check it out…

  5. Awesome, ive been looking for this to solve a weird bug having to do with animations pausing and resuming when the tab loses visibility.

    I’m pretty sure i understand it. If there is an animation that takes 1 second to complete, and you are in another tab for 10 seconds, then when you switch back the animation has to “catch up” and the animation is actually freaking out if you would. Here is an example on a coming soon page that has a countdown timer with the weird bug thing. http://thisisepic.com just switch tabs for a few seconds and then switch back and you will see what im talking about.

  6. I wonder if it works in iOS webkit as well…

  7. Henry

    A perfect feature for advanced phishing, http://www.azarask.in/blog/post/a-new-type-of-phishing-attack/

  8. Intead of support MooTools, it will be better to use special sugar library like Visibility.js https://github.com/ai/visibility.js

  9. CraftTheWeb

    Hey David, I think it is better to move document.hidden check to the bottom – that is probably cleaner way, just like in css prefixes you move unprefixed variant at the bottom.

    • CraftTheWeb

      Sorry, I didn’t pay attention, code in the article is great.

  10. As a potential workaround for older browsers, you could simply have a javascript timer that fires an event to stop updating.

    Then when the user moves the mouse on the page, using the mouse move event you could resume updating and also reset the timer each time they move their mouse.

    Obviously this wouldn’t work for things such as pages where they may not move their mouse whilst they watch a video, but perhaps you could experiment with other events such as focus to see how they behave.

  11. I wonder if the webkitHidden bit has changed since the move to blink. Doesn’t seem to be working on the latest Chrome.

    • document.webKitHidden is there in current Chrome.

  12. fr0z3nfyr

    The demo didn’t work for me on Mozilla Firefox 30.0. It worked fine on Chrome and IE.

  13. Raji

    Anyone have demo for “prerender” state?

  14. By the way, doesn’t document.onblur provides same functionality , i.e when the user clicks away you can have notification triggered ??

  15. Hello there. I recommend to use my library for it: http://dueljs.studentivan.ru/

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Recently on David Walsh Blog

  • OâReilly Velocity Conference â New York

    My favorite front-end conference has always been O'Reilly's Velocity Conference because the conference series has focused on one of the most undervalued parts of client side coding:  speed.  So often we're so excited that our JavaScript works that we forget that speed, efficiency, and performance are just as important. The next Velocity...

  • Free Download: Font Bundle Featuring 17 Incredible Typefaces

    The only thing we love more than a good font, is a good free font. So we’ve combed the Web for some of our favorite free fonts, and gathered them here in a single download. You’ll find a variety of useful typefaces, from highly geometric designs...

  • OâReilly Velocity Conference â Amsterdam

    My favorite front-end conference has always been O'Reilly's Velocity Conference because the conference series has focused on one of the most undervalued parts of client side coding:  speed.  So often we're so excited that our JavaScript works that we forget that speed, efficiency, and performance are just as important. The next Velocity...

  • CanIUse Command Line

    Every front-end developer should be well acquainted with CanIUse, the website that lets you view browser support for browser features.  When people criticize my blog posts for not detailing browser support for features within the post, I tell them to check CanIUse:  always up to date, unlike...

  • Generating Alternative Stylesheets for Browsers Without @media

    If your CSS code is built with a mobile-first approach, it probably contains all the rules that make up the "desktop" view inside @media statements. That's great, but browsers that don't support media queries (IE 8 and below) will simply ignore them, ending up getting the...