webpage-lifecycle
Version:
web页面生命周期
332 lines (277 loc) • 8.92 kB
JavaScript
class PAGE_EVENTS {
constructor() {
this.IS_SAFARI = typeof safari === "object" && safari.pushNotification;
const ua = window.navigator.userAgent.toLocaleLowerCase();
this.IS_IOS = /iphone|ipad|ipod/.test(ua);
this.IS_Android = /android/.test(ua);
this.reomveKey = "remove";
// 页面是否是离开(例如刷新、当前窗口点击外链,关闭浏览器窗口、提交表单请求等)
this.isLeave = false;
}
_isFunction(val) {
return typeof val === "function";
}
_isObject(val) {
return (
Object.prototype.toString.call(val).toLowerCase() === "[object object]"
);
}
_firstUpCase(val) {
return val.slice(0, 1).toUpperCase() + val.slice(1);
}
/**
* 当纯 HTML 被完全加载以及解析时,此时css、js不一定都加载完成
* @param {*} callback 监听回调函数
* @returns {remove : 移除监听方法}
*/
onReady(callback) {
const handel = () => {
this._isFunction(callback) && callback();
};
window.addEventListener("DOMContentLoaded", handle);
const obj = {};
obj[this.reomveKey] = () =>
window.removeEventListener("DOMContentLoaded", handel);
return obj;
}
/**
* 整个页面及所有依赖资源如样式表和图片都已完成加载时
* @param {*} callback 监听回调函数
* @returns {remove : 移除监听方法}
*/
onLoad(callback) {
const handel = () => {
this._isFunction(callback) && callback();
};
window.addEventListener("load", handel);
const obj = {};
obj[this.reomveKey] = () => window.removeEventListener("load", handel);
return obj;
}
/**
* 离开页面时,例如,刷新、当前窗口点击外链,关闭浏览器窗口、提交表单请求等
* @param {*} callback 监听回调函数
* @returns {remove : 移除监听方法}
*/
onLeave(callback) {
const handel = () => {
this.isLeave = true;
this._isFunction(callback) && callback();
};
window.addEventListener("pagehide", handel);
const obj = {};
obj[this.reomveKey] = () => window.removeEventListener("pagehide", handel);
return obj;
}
/**
* 页面显示时
* @param {*} callback 监听回调函数
* @returns {remove : 移除监听方法}
*/
onShow(callback) {
const handel = () => {
if (document.visibilityState === "visible") {
this._isFunction(callback) && callback();
}
};
document.addEventListener("visibilitychange", handel);
const obj = {};
obj[this.reomveKey] = () => {
document.removeEventListener("visibilitychange", handel);
};
return obj;
}
/**
* 页面最小化时、设备锁屏时、切到后台时
* @param {*} callback 监听回调函数
* @returns {remove : 移除监听方法}
*/
onHide(callback) {
const handel = (event) => {
// 如果是离开页面,将不再触发隐藏事件
//if (this.isLeave === true) return;
if (this.IS_SAFARI && event.persisted) {
this._isFunction(callback) && callback();
} else if (document.visibilityState === "hidden") {
if (this.isLeave === true) return;
this._isFunction(callback) && callback();
}
};
if (this.IS_SAFARI) window.addEventListener("pagehide", handel);
else document.addEventListener("visibilitychange", handel);
const obj = {};
obj[this.reomveKey] = () =>
this.IS_SAFARI
? window.removeEventListener("pagehide", handel)
: document.removeEventListener("visibilitychange", handel);
return obj;
}
/**
* 设备断网时
* @param {*} callback 监听回调函数
* @returns {remove : 移除监听方法}
*/
offLine(callback) {
const handel = () => {
this._isFunction(callback) && callback();
};
window.addEventListener("offline", handel);
const obj = {};
obj[this.reomveKey] = () => window.removeEventListener("offline", handel);
return obj;
}
/**
* 设备有网时
* @param {*} callback 监听回调函数
* @returns {remove : 移除监听方法}
*/
onLine(callback) {
const handel = () => {
this._isFunction(callback) && callback();
};
window.addEventListener("online", handel);
const obj = {};
obj[this.reomveKey] = () => window.removeEventListener("online", handel);
return obj;
}
/**
* 键盘弹出时,页面内输入框获取焦点,键盘弹出时
* @param {*} callback 监听回调函数
* @returns {remove : 移除监听方法}
*/
onKeyboardUp(callback) {
const handel = () => {
this._isFunction(callback) && callback();
};
document.body.addEventListener("focusin", handel);
const obj = {};
obj[this.reomveKey] = () =>
document.body.removeEventListener("focusin", handel);
return obj;
}
/**
* 键盘收起时,当点击输入框以外的其他页面区域,或者点击键盘自带的收起时
* @param {*} callback 监听回调函数
* @returns {remove : 移除监听方法}
*/
onKeyboardDown(callback) {
if (this.IS_IOS) {
const handel = () => {
this._isFunction(callback) && callback();
};
document.body.addEventListener("focusout", handel);
const obj = {};
obj[this.reomveKey] = () =>
document.body.removeEventListener("focusout", handel);
return obj;
} else if (this.IS_Android) {
const originHeight =
document.documentElement.clientHeight || document.body.clientHeight;
const handel = () => {
const resizeHeight =
document.documentElement.clientHeight || document.body.clientHeight;
const activeElement = document.activeElement;
if (resizeHeight < originHeight) {
if (
activeElement &&
(activeElement.tagName === "INPUT" ||
activeElement.tagName === "TEXTAREA")
) {
this._isFunction(callback) && callback();
}
}
};
window.addEventListener("resize", handel);
const obj = {};
obj[this.reomveKey] = () => window.removeEventListener("resize", handel);
return obj;
}
}
/**
* 设备横屏时
* @param {*} callback 监听回调函数
* @returns {remove : 移除监听方法}
*/
onLandscape(callback) {
const handel = () => {
if (window.innerHeight / window.innerWidth < 0.67) {
this._isFunction(callback) && callback();
}
};
window.addEventListener("resize", handel);
const obj = {};
obj[this.reomveKey] = () => {
window.removeEventListener("resize", handel);
};
return obj;
}
/**
* 设备竖屏时
* @param {*} callback 监听回调函数
* @returns {remove : 移除监听方法}
*/
onPortrait(callback) {
const handel = () => {
if (window.innerHeight / window.innerWidth > 0.67) {
this._isFunction(callback) && callback();
}
};
window.addEventListener("resize", handel);
const obj = {};
obj[this.reomveKey] = () => {
window.removeEventListener("resize", handel);
};
return obj;
}
/**
* storage储存值被更改时
* @param {*} key 被修改的数据键值
* @param {*} callback 监听回调函数
* @param {*} storageArea 属性值为被变动的 sessionStorage 对象或 localStorage 对象
* @returns {remove : 移除监听方法}
* @memberof PAGE_EVENTS
*/
onStorage(key, callback, storageArea) {
const iframe = document.createElement("iframe");
iframe.src = "/blank";
iframe.importance = "low";
document.body.appendChild(iframe);
const handel = (e) => {
if (storageArea && storageArea !== e.storageArea) return;
if (key && key !== e.key) return;
callback(e.newValue, e);
};
iframe.addEventListener("storage", handel);
const obj = {};
obj[this.reomveKey] = () => {
iframe.removeEventListener("storage", handel);
};
return obj;
}
/**
* 一次监听多个事件
* @param { ready, show, hide, leave, line, keyboardUp, keyboardDown, landscape, portrait, offLine, storage } config
* @returns {remove : 移除监听方法}
*/
on(config) {
if (!this._isObject(config)) return;
this._catchRemoveListenFunctions = [];
for (let key in config) {
const _key = ["offLine"].includes(key)
? key
: "on" + this._firstUpCase(key);
// alert(_key);
if (this._isFunction(this[_key]) && this._isFunction(config[key])) {
const result = this[_key](config[key]);
this._catchRemoveListenFunctions.push(result[this.reomveKey]);
}
}
const obj = {};
obj[this.reomveKey] = () => {
this._catchRemoveListenFunctions.forEach((handel) => handel());
this._catchRemoveListenFunctions = [];
};
return obj;
}
}
export default new PAGE_EVENTS();