浏览器功能(1) - JS判定当前页面是否显示在最前面
问题起因
前段时间遇到个奇葩需求,需要窗口每次显示在浏览器最前面时,都调用接口重新获取服务器时间,以确保定时器时间的准确性(相对的准确性)。
既然有需求,那么就要想办法去实现。
1、使用 visibilitychange
浏览器标签页在 被隐藏或显示 时都会触发 visibilitychange 事件。这里的隐藏包括:1、浏览器最小化(包括手动最小化浏览器;清屏操作);2、当前标签页被其他内容遮挡(要全部遮挡,部分遮挡不算);3、浏览器切换标签页
既然标签页在 被隐藏或显示 时都会触发事件,那么我们就监听 visibilitychange 事件即可。
document.addEventListener('visibilitychange', function() { console.log(document.visibilityState) if (document.visibilityState == 'hidden') { console.log('隐藏') alert('隐藏页面') } else if (document.visibilityState == 'visible') { console.log('显示') alert('显示页面') } })
2、使用onblur 和 onfocus
通过获取、失去焦点来判断页面是否在最前面。但这种方法有功能缺陷,详见下文。
let count = 1 window.addEventListener('focus', function() { // window获得焦点 console.log('window获得焦点') console.log('window获得焦点计数:', ++count) }) window.addEventListener('blur', function() { // window失去焦点 console.log('window失去焦点') console.log('window失去焦点计数:', --count) })
1、浏览器对象(即window对象) 是有 onfocus 和 onblur事件可以监听,但触发这两个事件的前提是页面之前是focus过的。也就是说如果页面刚刚渲染完(如刷新或新加载等)且鼠标一直停留在页面内的,此时不管用户在页面上有没有操作,页面都不会正常监听这两个事件。
2、如果页面在打开状态下,但是触发了 onblur 之后并无页面操作的情况下也不会正常监听这两个事件。直到,用户操作页面触发focus,之后离开页面才会触发blur,再次点击到当前页面时才会触发focus,如此反复都会触发相应的事件。
触发onblur事件的情况:
1、在chrome浏览器下,点击console面板也会触发blur事件,同样的,前提是之前是focus的状态。
2、页面最小化。
3、浏览器切换tab页面。
4、页面中的任何弹窗。
5、focus状态下切换到其他应用。
3、使用mouseover和mouseout事件监听
但是这种方法也有问题,下文叙述。
4、可以通过document.hidden属性判断当前页面是否是激活状态。
兼容性:IE10+,Firefox10+,Chrome14+,Opera12.1+,Safari7.1+
兼容性写法示例:
var hiddenProperty = 'hidden' in document ? 'hidden' : 'webkitHidden' in document ? 'webkitHidden' : 'mozHidden' in document ? 'mozHidden' : null; var visibilityChangeEvent = hiddenProperty.replace(/hidden/i, 'visibilitychange'); var onVisibilityChange = function(){ if (!document[hiddenProperty]) { console.log('页面非激活'); }else{ console.log('页面激活') } } document.addEventListener(visibilityChangeEvent, onVisibilityChange);