如何监听页面可见性,如处于后台、标签页切换、最小化、锁屏

// 是否是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

它所提供的全面的生命周期:

  • ACTIVE 激活
  • PASSIVE 未激活(页面可以看到,但焦点不在此页面,打开开发者工具可以触发此状态)
  • HIDDEN 隐藏,最小化、标签页切换都属于隐藏
  • FROZEN 冻结
  • TERMINATED 结束 (页面被关闭)
  • DISCARDED 废弃(页面内容被浏览器清空)

其中,从 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);
    }
});

你可能感兴趣的:(safari,javascript,前端)