Created
August 3, 2011 12:44
-
-
Save addyosmani/1122546 to your computer and use it in GitHub Desktop.
Cross-browser Page Visibility API polyfill
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* isVis - v0.5.5 Aug 2011 - Page Visibility API Polyfill | |
* Copyright (c) 2011 Addy Osmani | |
* Dual licensed under the MIT and GPL licenses. | |
*/ | |
(function () { | |
window.visibly = { | |
b: null, | |
q: document, | |
p: undefined, | |
prefixes: ['webkit', 'ms'], | |
props: ['VisibilityState', 'visibilitychange', 'Hidden'], | |
m: ['focus', 'blur'], | |
visibleCallbacks: [], | |
hiddenCallbacks: [], | |
_callbacks: [], | |
onVisible: function ( _callback ) { | |
this.visibleCallbacks.push(_callback); | |
}, | |
onHidden: function ( _callback ) { | |
this.hiddenCallbacks.push(_callback); | |
}, | |
isSupported: function () { | |
return (this._supports(0) || this._supports(1)); | |
}, | |
_supports: function ( index ) { | |
return ((this.prefixes[index] + this.props[2]) in this.q); | |
}, | |
runCallbacks: function ( index ) { | |
if ( index ) { | |
this._callbacks = (index == 1) ? this.visibleCallbacks : this.hiddenCallbacks; | |
for (var i = 0; i < this._callbacks.length; i++) { | |
this._callbacks[i](); | |
} | |
} | |
}, | |
_visible: function () { | |
window.visibly.runCallbacks(1); | |
}, | |
_hidden: function () { | |
window.visibly.runCallbacks(2); | |
}, | |
_nativeSwitch: function () { | |
((this.q[this.b + this.props[2]]) === true) ? this._hidden() : this._visible(); | |
}, | |
listen: function () { | |
try { /*if no native page visibility support found..*/ | |
if (!(this.isSupported())) { | |
if (document.addEventListener) { /*for browsers without focusin/out support eg. firefox, opera use focus/blur*/ | |
/*window used instead of doc as Opera complains otherwise*/ | |
window.addEventListener(this.m[0], this._visible, 1); | |
window.addEventListener(this.m[1], this._hidden, 1); | |
} else { /*IE <10s most reliable focus events are onfocusin/onfocusout*/ | |
this.q.attachEvent('onfocusin', this._visible); | |
this.q.attachEvent('onfocusout', this._hidden); | |
} | |
} else { /*switch support based on prefix*/ | |
this.b = (this._supports(0) == this.p) ? this.prefixes[1] : this.prefixes[0]; | |
this.q.addEventListener(this.b + this.props[1], function () { | |
window.visibly._nativeSwitch.apply(window.visibly, arguments); | |
}, 1); | |
} | |
} catch (e) {} | |
}, | |
init: function () { | |
this.listen(); | |
} | |
} | |
this.visibly.init(); | |
})(); | |
/*usage**/ | |
visibly.onVisible(function () { | |
document.title = 'visible' | |
}); | |
visibly.onVisible(function () { | |
console.log('visible'); | |
}); | |
visibly.onHidden(function () { | |
document.title = 'hidden'; | |
}); | |
visibly.onHidden(function () { | |
console.log('hidden'); | |
}); |
@zachleat
Honestly, IMO it can hardly be called a polyfill, as it doesn't fully reproduce the native Visibility behavior.
onblur and onfocus check the document's active state, which is still relevant and has its use today, separately from the Page Visibility API.
It is only relevant and a true polyfill in (non snapmode/split screen) mobile environments. Elsewhere, I am afraid it gives the wrong signal.
Works fine on Nexus5 with Chrome but fails on iPad3 iOS7 with Safari and Chrome ...
If someone gets here for some reason like myself trying to find a good polyfill of document.hidden
and the Page Visibility API, mind that this API is now well supported by browsers.
You could use this cool library too.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
First of all i forked from the @Swaagie fork because it supports natively firefox. After that i added two methods: isVisible and isHidden. Usage example:
So, it's better if you can check the visibility into the lambda func, wrapping the jquery effects into an isVisible test!
Reference: https://gist.github.com/mircobabini/3812165023fd671745ab