有没有一种方法可以检测浏览器窗口当前是否处于非活动状态?

727

我有一段定期执行的JavaScript代码。当用户不在浏览网站时(即窗口或选项卡没有焦点),最好不要运行它。

是否有一种使用JavaScript实现此功能的方法?

我的参考对象是 Gmail 聊天,如果你正在使用的窗口不活跃,它会播放声音。


12
如果您对以下答案不满意,请查看 requestAnimationFrame API,或使用现代特性,即当窗口不可见时 setTimeout/setInterval 的频率会降低(例如在 Chrome 中约为1秒)。请注意,翻译尽可能保持原意,简化表达,并避免添加解释。 - Rob W
4
document.body.onblur=function(e){console.log('lama');} 可以用于非聚焦元素。 - WhyMe
3
请参考这个答案,它使用W3C页面可见性API来实现跨浏览器兼容,并在不支持该API的浏览器中回退到blur/focus - Mathias Bynens
8
以下80%的回答“不是对这个问题的回答”。该问题询问“目前未激活的”,而下面大量回答是关于“不可见”的,这不是对这个问题的回答。它们应该被标记为“不是答案”。 - gman
1
大多数人谈论“非活动”时,实际上是指“非活动且不可见”。只是“非活动”很容易 - 只需处理窗口的blur / focus事件...尽管如此,这将具有有限的用途,因为窗口可以是非活动的但完全或部分可见(某些任务栏中也有“预览”图标,人们希望继续更新)。 - rustyx
1
Twitter 会在页面顶部刷新页面,如果用户一段时间未打开该页面,并且有新的消息时,则会自动跳转到该标签页或窗口,这样用户就可以轻松找到他们需要的内容。 - gseattle
25个回答

1
如果您想在整个浏览器模糊时采取行动: 正如我所评论的,如果浏览器失去焦点,则建议的事件都不会触发。我的想法是在循环中计数并在事件触发时重置计数器。如果计数器达到限制,我会将location.href重定向到另一个页面。这也会在使用开发工具时触发。
var iput=document.getElementById("hiddenInput");
   ,count=1
   ;
function check(){
         count++;
         if(count%2===0){
           iput.focus();
         }
         else{
           iput.blur();
         }
         iput.value=count;  
         if(count>3){
           location.href="http://Nirwana.com";
         }              
         setTimeout(function(){check()},1000);
}   
iput.onblur=function(){count=1}
iput.onfocus=function(){count=1}
check();

这是在火狐浏览器上测试成功的草稿。

1

我重新阅读了@daniel-buckmaster的版本,虽然我没有进行多次尝试,但是这段代码对我来说更加优雅...

// on-visibility-change.js v1.0.1, based on https://dev59.com/d3NA5IYBdhLWcg3wL6sc
function onVisibilityChange(callback) {
    let d = document;
    let visible = true;
    let prefix;
    if ('hidden' in d) {
        prefix = 'h';
    } else if ('webkitHidden' in d) {
        prefix = 'webkitH';
    } else if ('mozHidden' in d) {
        prefix = 'mozH';
    } else if ('msHidden' in d) {
        prefix = 'msH';
    } else if ('onfocusin' in d) { // ie 9 and lower
        d.onfocusin = focused;
        d.onfocusout = unfocused;
    } else { // others
        window.onpageshow = window.onfocus = focused;
        window.onpagehide = window.onblur = unfocused;
    };
    if (prefix) {
        visible = !d[prefix + 'idden'];
        d.addEventListener(prefix.substring(0, prefix.length - 1) + 'visibilitychange', function() {
            (d[prefix + 'idden'] ? unfocused : focused)();
        });
    };

    function focused() {
        if (!visible) {
            callback(visible = true);
        };
    };

    function unfocused() {
        if (visible) {
            callback(visible = false);
        };
    };
};

1

如果你想使用React中的状态(state)来实现这个功能,可以参考下面的实现:


import React, { useState, useEffect } from 'react';

function MyComponent() {
  const [tabActive, setTabActive] = useState(true);

  useEffect(() => {
    const handleVisibilityChange = () => {
      setTabActive(!document.hidden);
    };

    document.addEventListener('visibilitychange', handleVisibilityChange);

    return () => {
      document.removeEventListener('visibilitychange', handleVisibilityChange);
    };
  }, []);

  // your component code here
}


0

我的代码

let browser_active = ((typeof document.hasFocus != 'undefined' ? document.hasFocus() : 1) ? 1 : 0);
if (!browser_active) {
 // active
} 

0

这里有一个坚实、现代的解决方案。(简短而精炼)

document.addEventListener("visibilitychange", () => {
  console.log( document.hasFocus() )
})

这将设置一个监听器,以在任何可见性事件被触发时触发,这可能是焦点或模糊。


3
无法使用 Alt-Tab(切换到其他应用程序)。 - iair
这里的alt + tab可以正常使用...(Chrome 91) - Luis Lobo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接