Skip to content

Instantly share code, notes, and snippets.

@Zirak
Created January 25, 2012 16:15
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save Zirak/1677020 to your computer and use it in GitHub Desktop.
Save Zirak/1677020 to your computer and use it in GitHub Desktop.
Visibility API
//http://www.w3.org/TR/2011/WD-page-visibility-20110602/
(function () {
"use strict";
//no need to shim if it's already there
if ( 'hidden' in document && 'onvisibilitychange' in document ) {
return;
}
//fail silently if the browser sux
if (
!Array.prototype.forEach ||
!Object.defineProperty ||
!document.addEventListener ||
!window.addEventListener
) {
return;
}
//check to see if there's a native implementation
var prefixes = [ 'webkit', 'moz', 'o', 'ms' ], nativeName = '';
prefixes.some(function ( prefix ) {
if ( (prefix + 'Hidden') in document ) {
nativeName = prefix;
return true;
}
});
var hiddenGetter;
if ( nativeName ) {
hiddenGetter = function () {
return document[ nativeName + 'Hidden' ];
};
} else {
hiddenGetter = function () {
return hidden;
};
}
//corresponding values to document.hidden
var visibilityStates = {
'true' : 'hidden',
'false' : 'visible'
};
var stateGetter = function () {
return visibilityStates[ document.hidden ];
};
//will be called whenever the visibility has been changed
var visibilityChange = function () {
document.hidden = hiddenGetter();
document.visibilityState = stateGetter();
//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 nativeName functionality
if ( nativeName ) {
document.addEventListener(
nativeName + 'visibilitychange',
visibilityChange,
false );
} else {
//the window.focus and window.blur events are, well, close enough
window.addEventListener( 'focus', function () {
hidden = false;
visibilityChange();
}, false );
window.addEventListener( 'blur', function () {
hidden = true;
visibilityChange();
}, false );
}
//add document.hidden, document.visibilityState and
// document.onvisibilitychange
Object.defineProperties(document, {
hidden : {
value : hiddenGetter(),
writable : true,
configurable : true
},
visibilityState : {
value : stateGetter(),
writable : true,
configurable : true
},
onvisibilitychange : {
value : null,
writable : true,
configurable : true
}
});
}());
@Raynos
Copy link

Raynos commented Jan 25, 2012

Test window.addEventListener as well.

@Zirak
Copy link
Author

Zirak commented Jan 25, 2012

@Raynos Thanks, it managed to slip through. Also added a link to the w3c page.

@termi
Copy link

termi commented Jan 31, 2012

Note:

  1. Google Closure Compiler can't parse your code due 'native' word
  2. addEventListener without 3rd parameter didn't work in FF 3.6 and lower due to bug and it can't be shimed

@Zirak
Copy link
Author

Zirak commented Jan 31, 2012

@termi1uc1 Thanks for those, forgot about the third parameter. Fixed.

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