js监听当前页面是否活跃/失活
429 字
2 分钟
js监听当前页面是否活跃/失活
- window.addEventListener(‘focus/blur’, …)
- window.addEventListener(‘visibilitychange’, …)
a. 回调中使用
document.hidden或document.visibilityState属性检测页面可见性 b. 兼容性不好,需要pagehide辅助
差异: 在移动设备上,管理标签(如下图)时,focus & blur 认为已经 blur 了,visibilitychange 认为还是活跃的

在 MAC 上,合盖后无法触发 visibilitychange,会在下次打开电脑后快速的触发 2 次 visibilitychange(一次为失活,一次为重新活跃),focus & blur 就没有这个问题
// visibilitychangeconst emptyCb = () => {}class PageVisibilityChangeListener { private eventsMap: Map<[CB, CB], CB> = new Map() private listenerFn: (visibleCb: CB, hiddenCb: CB) => CB private visibilityChangeEventName: string constructor() { const hiddenProperty = 'hidden' in document ? 'hidden' : 'webkitHidden' in document ? 'webkitHidden' : 'mozHidden' in document ? 'mozHidden' : null this.visibilityChangeEventName = hiddenProperty?.replace(/hidden/i, 'visibilitychange') || '' if (!hiddenProperty) console.log('页面激活状态监听失败') let lastTime = 0 let timer = 0 this.listenerFn = (visibleCb: CB, hiddenCb: CB) => (e) => { const t = new Date().getTime() if (t - lastTime < 50) { clearTimeout(timer) lastTime = t return } if (document.visibilityState === 'visible') { // @ts-ignore timer = setTimeout(() => visibleCb(e), 50) } else if (document.visibilityState === 'hidden') { // @ts-ignore timer = setTimeout(() => hiddenCb(e), 50) } lastTime = t } } on(visibleCb: CB | null, hiddenCb: CB | null) { if (!this.visibilityChangeEventName || (!visibleCb && !hiddenCb)) return visibleCb = visibleCb || emptyCb hiddenCb = hiddenCb || emptyCb const fn = this.listenerFn(visibleCb, hiddenCb) this.eventsMap.set([visibleCb, hiddenCb], fn) listener.on(this.visibilityChangeEventName, fn) } off(visibleCb: CB | null, hiddenCb: CB | null) { if (!this.visibilityChangeEventName || (!visibleCb && !hiddenCb)) return visibleCb = visibleCb || emptyCb hiddenCb = hiddenCb || emptyCb const fn = this.eventsMap.get([visibleCb, hiddenCb]) fn && listener.off(this.visibilityChangeEventName, fn) }}/** 监听页面失活 */export const pageVisibilityChangeListener = new PageVisibilityChangeListener()pageVisibilityChangeListener.on( () => console.log('页面复活'), () => console.log('页面失活'))// focus & blurclass PageVisibilityChangeListener { constructor() {} on(visibleCb: CB | null, hiddenCb: CB | null) { if (visibleCb) listener.on('focus', visibleCb) if (hiddenCb) listener.on('blur', hiddenCb) } off(visibleCb: CB | null, hiddenCb: CB | null) { if (visibleCb) listener.off('focus', visibleCb) if (hiddenCb) listener.off('blur', hiddenCb) }}/** 监听页面失活 */export const pageVisibilityChangeListener = new PageVisibilityChangeListener()pageVisibilityChangeListener.on( () => console.log('页面聚焦'), () => console.log('页面失焦')) js监听当前页面是否活跃/失活
https://wangxiang.website/posts/语言基础/page-alive/