Skip to content

Instantly share code, notes, and snippets.

@Raynos
Forked from Zirak/gist:1677020
Created January 25, 2012 18:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Raynos/1677639 to your computer and use it in GitHub Desktop.
Save Raynos/1677639 to your computer and use it in GitHub Desktop.
Visibility API
// assumes an ES5 compliant browser for Array.prototype.forEach
// and Object.defineProperty
// and a sane browser for Element.prototype.addEventListener
(function () {
"use strict";
//no need to shim if it's already there
if ( 'hidden' in document && 'onvisibilitychange' in document ) {
return;
}
// no-op on legacy browsers.
if ( !document.addEventListener ||
!Array.prototype.forEach ||
!Object.defineProperty ||
!window.addEventListener
) {
return;
}
//check to see if there's a native implementation
var prefixes = [ 'webkit', 'moz', 'o', 'ms' ], native = '', hiddenName = 'hidden';
prefixes.forEach(function ( prefix ) {
if ( (prefix + 'Hidden') in document ) {
native = prefix;
hiddenName = prefix + 'Hidden';
}
});
//will be called whenever the visibility has been changed
var visibilityChange = function () {
document[hiddenName] = hidden;
document.visibilityState = document.hidden ? 'hidden' : 'visible';
//create the visibilitychange event
var evt = document.createEvent( 'Event' );
evt.initEvent( 'visibilitychange', true, true );
//you're FIRED!
document.dispatchEvent( evt );
//check for document.onvisibilitychange and call it if it exists
var vischange = 'onvisibilitychange'; //it's really long to write...
if ( document[vischange] && document[vischange].call ) {
document[ vischange ].call( document, evt );
}
}, hidden = false;
//add the event listeners to tap into native functionality
if ( native ) {
document.addEventListener( native + 'visibilitychange', visibilityChange );
} else {
//the window.focus and window.blur events are, well, close enough
window.addEventListener( 'focus', function () {
hidden = false;
visibilityChange();
});
window.addEventListener( 'blur', function () {
hidden = true;
visibilityChange();
});
}
//add document.hidden, document.visibilityState
Object.defineProperty( document, 'hidden', {
value: hidden,
configurable: true
});
Object.defineProperty( document, 'visibilityState', {
value: document.hidden ? 'hidden' : 'visible',
configurable: true
});
}());
@domenic
Copy link

domenic commented Jan 25, 2012

The onvisibilitychange addition wasn't useless; it made it non-enumerable and null instead of undefined, like all other document.onwhatever properties.

@Raynos
Copy link
Author

Raynos commented Jan 25, 2012

@DomenicDenicola document.onclick === undefined; // true in Firefox.

@domenic
Copy link

domenic commented Jan 25, 2012

Not in Firefox 9... I'd screenshot my console window if I was a bit less lazy.

@Zirak
Copy link

Zirak commented Jan 25, 2012

@Raynos defineProperty defines the property, it's an "I exist, acknowledge me". That way, things like the test in the beginning of the script, 'onvisibilitychange' in document, will give the correct results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment