Skip to content

Instantly share code, notes, and snippets.

@vincentorback
Last active April 14, 2020 22:39
Show Gist options
  • Save vincentorback/d3be9a84fa58cd7bf8d8c1f675549857 to your computer and use it in GitHub Desktop.
Save vincentorback/d3be9a84fa58cd7bf8d8c1f675549857 to your computer and use it in GitHub Desktop.
function onVisibilityChange (callbackHidden, callbackVisible) {
var browserPrefixes = ['moz', 'ms', 'o', 'webkit']
var isVisible = true // internal flag, defaults to true
// get the correct attribute name
function getHiddenPropertyName (prefix) {
return (prefix ? prefix + 'Hidden' : 'hidden')
}
// get the correct event name
function getVisibilityEvent (prefix) {
return (prefix || '') + 'visibilitychange'
}
// get current browser vendor prefix
function getBrowserPrefix () {
for (var i = 0; i < browserPrefixes.length; i++) {
if (getHiddenPropertyName(browserPrefixes[i]) in document) {
// return vendor prefix
return browserPrefixes[i]
}
}
// no vendor prefix needed
return null
}
// bind and handle events
var browserPrefix = getBrowserPrefix()
var hiddenPropertyName = getHiddenPropertyName(browserPrefix)
var visibilityEventName = getVisibilityEvent(browserPrefix)
function onVisible () {
// prevent double execution
if (isVisible) {
return
}
// change flag value
isVisible = true
if (callbackVisible)
callbackVisible()
}
}
function onHidden () {
// prevent double execution
if (!isVisible) {
return
}
// change flag value
isVisible = false
if (callbackHidden) {
callbackHidden()
}
}
function handleVisibilityChange (forcedFlag) {
// forcedFlag is a boolean when this event handler is triggered by a
// focus or blur eventotherwise it's an Event object
if (typeof forcedFlag === 'boolean') {
if (forcedFlag) {
return onVisible()
}
return onHidden()
}
if (document[hiddenPropertyName]) {
return onHidden()
}
return onVisible()
}
document.addEventListener(visibilityEventName, handleVisibilityChange, false)
// extra event listeners for better behaviour
document.addEventListener('focus', function () {
handleVisibilityChange(true)
}, false)
document.addEventListener('blur', function () {
handleVisibilityChange(false)
}, false)
window.addEventListener('focus', function () {
handleVisibilityChange(true)
}, false)
window.addEventListener('blur', function () {
handleVisibilityChange(false)
}, false)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment