<div>Hi all,</div><div><br></div><div>On the Chromium team we’ve identified a couple of use cases that we’d like to address with a simple API, and we’d love your feedback.</div><div><br></div><div>In particular, there is currently no good way for a web page to detect that it is a background tab and is thus completely invisible to the user, although some heuristics do exist (like detecting mousemove events). In the future, there may be cases where such detection is even more important, for example in the prerendering feature (<a href="http://code.google.com/p/chromium/issues/detail?id=61745" target="_blank">http://code.google.com/p/chromium/issues/detail?id=61745</a>) that Chromium is currently in the early stages of experimentation with.</div>
<div><br></div><div>==Use cases==</div><div>* A puzzle game has a timer that keeps track of how long the user has taken to solve the puzzle. It wants to pause the timer when the user has hidden the tab.</div><div>* A web app that uses polling to fetch dynamic content can pause polling when it knows the page is hidden from the user.</div>
<div>* A streaming video site doesn’t want to start the video until the user actually views the tab for the first time (i.e. video shouldn’t start automatically if a user opens the tab in the background).</div><div>* A page wants to detect when it is being prerendered so it can behave appropriately.</div>
<div>* A page wants to detect when it is moving into or out of the back-forward cache.</div><div><br></div><div><br></div><div>With these use-cases in mind, there are a number of requirements.</div><div><br></div><div>==Requirements==</div>
<div>* Easy for developers to write scripts that fall back on old behaviors for browsers that do not implement this API</div><div>* Ability to query the document’s current visibility state</div><div>* Events fired when the document transitions between visibility states</div>
<div>* Ability for browser vendors to add new visibility states in the future</div><div><br></div><div><br></div><div>==Strawman API==</div><div>What follows is a proposed API that fits the requirements. Note that another route would be to attempt a mostly-compatible extension of Mozilla’s existing pageshow and pagehide events, which would not necessarily be perfectly backwards compatible.</div>
<div><br></div><div>=document.visibility=</div><div>A read-only property that returns a string, one of:</div><div>* “visible” : the tab is focused in its window</div><div>* “hidden” : the tab is backgrounded within its window</div>
<div>* “prerender” : the tab is currently being loaded in an off-screen tab, and may never be shown to the user.</div><div>* “cache” : the tab is currently in the back-forward-cache. Note that in Mozilla’s current implementation, document.visibility would never actually be “cache” because Javascript cannot execute when in the cache.</div>
<div><br></div>
<div>In the future, the list of possible values may be extended. Of these states in this list, all except “visible” are considered to be hidden. Developers can use the existence of this property to know that they can rely on the rest of this API, too.</div>
<div><br></div><div>=document.isVisible=</div><div>A simple convenience read-only property that returns a boolean. Returns true if document.visibility’s current value is in the set of visibility states considered to be visible (for the first iteration of this API, that would only include the “visible” state).</div>
<div><br></div><div>=visibilitychanged=</div><div>A simple event, fired at the document object immediately after document.visibility transitions between visibility states. The event has a property, fromState, that is set to the value of document.visibility just before it was changed to the current value. Note that visibility has nothing to do with whether the document’s contents have fully loaded or not, which implies that for any given visibility transition event, onload may or may not have already fired.</div>
<div><br></div><div>Thoughts or comments are welcome.</div><div><br></div><div>--Alex Komoroske</div>