- // 是否是safari浏览器
- const IS_SAFARI = typeof safari === 'object' && safari.pushNotification;
-
- /**
- * 监听dom状态
- * @param { function } showCallback:页面在前景标签页中,并且窗口没有最小化时,的回调函数
- * @param { function } hideCallback: 标签页处于后台时、窗口被最小化时、设备的屏幕被关闭时,的回调函数
- */
- const ListenDocuemntState = function (showCallback, hideCallback){
-
- let _showCallback = showCallback || function(){ };
- let _hideCallback = hideCallback || function(){ };
-
- const visibilitychangeHandel = () => {
- /** 当:
- * document的标签页处于后台
- * 窗口被最小化
- * 设备的屏幕被关闭。
- */
- if(document.visibilityState === 'hidden'){
- _hideCallback()
- }
- /**
- * 当:页面内容至少是部分可见. 即此页面在前景标签页中,并且窗口没有最小化
- */
- else if(document.visibilityState === 'visible'){
- // 定时器的原因是想页面第一次渲染完毕后触发
- setTimeout(() => _showCallback(), 0)
- }
- }
- const pagehideHandel = () => _hideCallback();
-
-
- document.addEventListener('visibilitychange', visibilitychangeHandel, false);
- //Safari浏览器在页面hidden时存在兼容问题
- if ( IS_SAFARI ) window.addEventListener('pagehide', pagehideHandel);
-
- return {
- reomve: function(){
- document.removeEventListener('visibilitychange', visibilitychangeHandel);
- if ( IS_SAFARI ) window.addEventListener('pagehide', pagehideHandel);
- }
- }
- }
-
- export default ListenDocuemntState;
使用方法:
- import ListenDocuemntState from 'ListenDocuemntState'
-
- const listen = ListenDocuemntState (()=>{
- // 页面可见了 dosomething...
-
- }, ()=>{
- // 页面不可见了 dosomething...
-
- })
-
-
- // 移除
- listen.remove()
另外推荐一个由谷歌团队维护的页面生命周期的方案:https://github.com/GoogleChromeLabs/page-lifecycle
它所提供的全面的生命周期:
其中,从 HIDDEN 状态到 FROZEN 状态之间的变化是有新的 API 事件名称检测的,分别是 resume 事件和 freeze 事件,使用示意如下:
- document.addEventListener('freeze', (event) => {
- // 页面被冻结
- });
-
- document.addEventListener('resume', (event) => {
- // 页面解冻了
- });
例如,我们希望页面离开时候上报数据,可以试试下面的代码,理论上应该是没问题的:
- lifecycle.addEventListener('statechange', function(event) {
- if (event.oldState == 'passive' && event.newState == 'hidden') {
- navigator.sendBeacon('/log', postData);
- }
- });