2018-05-23 01:03:08 +08:00
|
|
|
const VISIBILITY_TIMEOUT = 5000;
|
|
|
|
|
2018-05-03 01:53:53 +08:00
|
|
|
export default class VisibilityEvent {
|
2019-08-02 00:47:45 +08:00
|
|
|
constructor() {
|
2018-05-03 01:53:53 +08:00
|
|
|
this._onVisible = null;
|
|
|
|
this._onHidden = null;
|
|
|
|
|
|
|
|
this._handleVisibilityChange = this._handleVisibilityChange.bind(this);
|
|
|
|
|
|
|
|
this._registerVisibilityEvent();
|
2018-05-23 01:03:08 +08:00
|
|
|
|
|
|
|
this._onHiddenTimeout = null;
|
2018-05-03 01:53:53 +08:00
|
|
|
}
|
|
|
|
|
2019-08-02 00:47:45 +08:00
|
|
|
onVisible(onVisibleCallback) {
|
2018-05-23 01:03:08 +08:00
|
|
|
this._onVisible = () => {
|
|
|
|
if (!this._isHidden()) {
|
2018-05-30 02:54:01 +08:00
|
|
|
onVisibleCallback();
|
2018-05-23 01:03:08 +08:00
|
|
|
}
|
|
|
|
};
|
2018-05-03 01:53:53 +08:00
|
|
|
}
|
|
|
|
|
2018-05-30 02:54:01 +08:00
|
|
|
onHidden(onHiddenCallback) {
|
2018-05-23 01:03:08 +08:00
|
|
|
this._onHidden = () => {
|
|
|
|
if (this._isHidden()) {
|
2018-05-30 02:54:01 +08:00
|
|
|
onHiddenCallback();
|
2018-05-23 01:03:08 +08:00
|
|
|
this._onHiddenTimeout = null;
|
|
|
|
}
|
|
|
|
};
|
2018-05-03 01:53:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
removeEventListeners() {
|
2019-08-02 00:47:45 +08:00
|
|
|
const event = this._getVisibilityEvent();
|
2018-05-03 01:53:53 +08:00
|
|
|
document.removeEventListener(event, this._handleVisibilityChange, false);
|
|
|
|
}
|
|
|
|
|
2019-08-02 00:47:45 +08:00
|
|
|
_handleVisibilityChange() {
|
2018-05-03 01:53:53 +08:00
|
|
|
if (!this._isHidden()) {
|
|
|
|
if (this._onVisible) {
|
2018-05-23 01:03:08 +08:00
|
|
|
if (this._onHiddenTimeout) {
|
|
|
|
clearTimeout(this._onHiddenTimeout);
|
|
|
|
this._onHiddenTimeout = null;
|
|
|
|
} else {
|
|
|
|
this._onVisible();
|
|
|
|
}
|
2018-05-03 01:53:53 +08:00
|
|
|
}
|
2019-08-02 00:47:45 +08:00
|
|
|
} else if (this._onHidden) {
|
|
|
|
if (!this._onHiddenTimeout) {
|
|
|
|
this._onHiddenTimeout = setTimeout(this._onHidden.bind(this), VISIBILITY_TIMEOUT);
|
2018-05-03 01:53:53 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-02 00:47:45 +08:00
|
|
|
_getHiddenProp() {
|
|
|
|
const prefixes = ['webkit', 'moz', 'ms', 'o'];
|
2018-05-03 01:53:53 +08:00
|
|
|
|
|
|
|
// if 'hidden' is natively supported just return it
|
|
|
|
if ('hidden' in document) return 'hidden';
|
|
|
|
|
|
|
|
// otherwise loop over all the known prefixes unti we find one
|
2019-08-02 00:47:45 +08:00
|
|
|
for (let i = 0; i < prefixes.length; i++) {
|
|
|
|
if ((`${prefixes[i]}Hidden`) in document) {
|
|
|
|
return `${prefixes[i]}Hidden`;
|
2018-05-03 01:53:53 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// otherwise it's not supported
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2019-08-02 00:47:45 +08:00
|
|
|
_isHidden() {
|
|
|
|
const prop = this._getHiddenProp();
|
2018-05-03 01:53:53 +08:00
|
|
|
|
|
|
|
if (!prop) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return document[prop];
|
|
|
|
}
|
|
|
|
|
|
|
|
_getVisibilityEvent() {
|
2019-08-02 00:47:45 +08:00
|
|
|
let visibilityChange;
|
|
|
|
if (typeof document.hidden !== 'undefined') {
|
|
|
|
visibilityChange = 'visibilitychange';
|
|
|
|
} else if (typeof document.msHidden !== 'undefined') {
|
|
|
|
visibilityChange = 'msvisibilitychange';
|
|
|
|
} else if (typeof document.webkitHidden !== 'undefined') {
|
|
|
|
visibilityChange = 'webkitvisibilitychange';
|
2018-05-03 01:53:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return visibilityChange;
|
|
|
|
}
|
|
|
|
|
2019-08-02 00:47:45 +08:00
|
|
|
_registerVisibilityEvent() {
|
|
|
|
const event = this._getVisibilityEvent();
|
2018-05-03 01:53:53 +08:00
|
|
|
document.addEventListener(event, this._handleVisibilityChange, false);
|
|
|
|
}
|
|
|
|
}
|