File size: 6,509 Bytes
f5b0947 | 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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | ;(function (global) {
var lastId = -1;
// Visibility.js allow you to know, that your web page is in the background
// tab and thus not visible to the user. This library is wrap under
// Page Visibility API. It fix problems with different vendor prefixes and
// add high-level useful functions.
var self = {
// Call callback only when page become to visible for user or
// call it now if page is visible now or Page Visibility API
// doesn’t supported.
//
// Return false if API isn’t supported, true if page is already visible
// or listener ID (you can use it in `unbind` method) if page isn’t
// visible now.
//
// Visibility.onVisible(function () {
// startIntroAnimation();
// });
onVisible: function (callback) {
var support = self.isSupported();
if ( !support || !self.hidden() ) {
callback();
return support;
}
var listener = self.change(function (e, state) {
if ( !self.hidden() ) {
self.unbind(listener);
callback();
}
});
return listener;
},
// Call callback when visibility will be changed. First argument for
// callback will be original event object, second will be visibility
// state name.
//
// Return listener ID to unbind listener by `unbind` method.
//
// If Page Visibility API doesn’t supported method will be return false
// and callback never will be called.
//
// Visibility.change(function(e, state) {
// Statistics.visibilityChange(state);
// });
//
// It is just proxy to `visibilitychange` event, but use vendor prefix.
change: function (callback) {
if ( !self.isSupported() ) {
return false;
}
lastId += 1;
var number = lastId;
self._callbacks[number] = callback;
self._listen();
return number;
},
// Remove `change` listener by it ID.
//
// var id = Visibility.change(function(e, state) {
// firstChangeCallback();
// Visibility.unbind(id);
// });
unbind: function (id) {
delete self._callbacks[id];
},
// Call `callback` in any state, expect “prerender”. If current state
// is “prerender” it will wait until state will be changed.
// If Page Visibility API doesn’t supported, it will call `callback`
// immediately.
//
// Return false if API isn’t supported, true if page is already after
// prerendering or listener ID (you can use it in `unbind` method)
// if page is prerended now.
//
// Visibility.afterPrerendering(function () {
// Statistics.countVisitor();
// });
afterPrerendering: function (callback) {
var support = self.isSupported();
var prerender = 'prerender';
if ( !support || prerender != self.state() ) {
callback();
return support;
}
var listener = self.change(function (e, state) {
if ( prerender != state ) {
self.unbind(listener);
callback();
}
});
return listener;
},
// Return true if page now isn’t visible to user.
//
// if ( !Visibility.hidden() ) {
// VideoPlayer.play();
// }
//
// It is just proxy to `document.hidden`, but use vendor prefix.
hidden: function () {
return !!(self._doc.hidden || self._doc.webkitHidden);
},
// Return visibility state: 'visible', 'hidden' or 'prerender'.
//
// if ( 'prerender' == Visibility.state() ) {
// Statistics.pageIsPrerendering();
// }
//
// Don’t use `Visibility.state()` to detect, is page visible, because
// visibility states can extend in next API versions.
// Use more simpler and general `Visibility.hidden()` for this cases.
//
// It is just proxy to `document.visibilityState`, but use
// vendor prefix.
state: function () {
return self._doc.visibilityState ||
self._doc.webkitVisibilityState ||
'visible';
},
// Return true if browser support Page Visibility API.
// refs: https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
//
// if ( Visibility.isSupported() ) {
// Statistics.startTrackingVisibility();
// Visibility.change(function(e, state)) {
// Statistics.trackVisibility(state);
// });
// }
isSupported: function () {
return self._doc.hidden !== undefined || self._doc.webkitHidden !== undefined;
},
// Link to document object to change it in tests.
_doc: document || {},
// Callbacks from `change` method, that wait visibility changes.
_callbacks: { },
// Listener for `visibilitychange` event.
_change: function(event) {
var state = self.state();
for ( var i in self._callbacks ) {
self._callbacks[i].call(self._doc, event, state);
}
},
// Set listener for `visibilitychange` event.
_listen: function () {
if ( self._init ) {
return;
}
var event = 'visibilitychange';
if ( self._doc.webkitVisibilityState ) {
event = 'webkit' + event;
}
var listener = function () {
self._change.apply(self, arguments);
};
if ( self._doc.addEventListener ) {
self._doc.addEventListener(event, listener);
} else {
self._doc.attachEvent(event, listener);
}
self._init = true;
}
};
if ( typeof(module) != 'undefined' && module.exports ) {
module.exports = self;
} else {
global.Visibility = self;
}
})(this);
|