public
Created — forked from Zirak/gist:1677020

Visibility API

  • Download Gist
gistfile1.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
// 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
});
}());

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

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

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

@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.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.