是否有一种可靠的跨浏览器方法来检测标签是否有焦点。

这个场景是,我们有一个定期轮询股票价格的应用程序,如果页面没有焦点,我们可以停止轮询并节省所有人的交通噪音,特别是当人们喜欢打开不同投资组合的几个选项卡时。

是窗口。打开模糊和窗口。Onfocus这个选项?


当前回答

一个React钩子版本,基于上面所有这些优秀的先生们的回答:

import { useEffect, useState } from 'react';

const EVENT_NAME = 'visibilitychange';

export const useTabFocus = () => {
    const [hasFocus, setHasFocus] = useState(isVisible());

    useEffect(() => {
        const onVisibilityChange = () => {
            setHasFocus(isVisible());
        };

        document.addEventListener(EVENT_NAME, onVisibilityChange);

        return () => {
            document.removeEventListener(EVENT_NAME, onVisibilityChange);
        };
    }, []);

    return hasFocus;
};

const isVisible = () => document.visibilityState === 'visible';

其他回答

奇怪的是没有人提到document.hasFocus

if (document.hasFocus()) console.log('Tab is active')

MDN有更多信息。

一个React钩子版本,基于上面所有这些优秀的先生们的回答:

import { useEffect, useState } from 'react';

const EVENT_NAME = 'visibilitychange';

export const useTabFocus = () => {
    const [hasFocus, setHasFocus] = useState(isVisible());

    useEffect(() => {
        const onVisibilityChange = () => {
            setHasFocus(isVisible());
        };

        document.addEventListener(EVENT_NAME, onVisibilityChange);

        return () => {
            document.removeEventListener(EVENT_NAME, onVisibilityChange);
        };
    }, []);

    return hasFocus;
};

const isVisible = () => document.visibilityState === 'visible';

重要编辑:这个答案已经过时了。在编写它之后,引入了可见性API (mdn,示例,规范)。这是解决这个问题更好的办法。


var focused = true;

window.onfocus = function() {
    focused = true;
};
window.onblur = function() {
    focused = false;
};

AFAIK,焦点和模糊都支持…所有东西。(见http://www.quirksmode.org/dom/events/index.html)

是的,窗户。Onfocus和window。Onblur应该适用于你的场景:

http://www.thefutureoftheweb.com/blog/detect-browser-window-focus

跨浏览器jQuery解决方案!原始可在GitHub

有趣且易于使用!

下面的插件将通过各种版本的IE, Chrome, Firefox, Safari等的标准测试。并相应地建立您所声明的方法。它还涉及以下问题:

onblur | .blur /聚焦事件|。关注“重复”呼叫 通过选择替代应用程序,如word,窗口失去焦点 这往往是不受欢迎的,因为,如果你有一个银行页面打开,它的onblur事件告诉它掩盖页面,然后如果你打开计算器,你不能再看到页面! 不触发页面加载

使用非常简单:向下滚动到“运行代码段”

$.winFocus(function(event, isVisible) {
    console.log("Combo\t\t", event, isVisible);
});

//  OR Pass False boolean, and it will not trigger on load,
//  Instead, it will first trigger on first blur of current tab_window
$.winFocus(function(event, isVisible) {
    console.log("Combo\t\t", event, isVisible);
}, false);

//  OR Establish an object having methods "blur" & "focus", and/or "blurFocus"
//  (yes, you can set all 3, tho blurFocus is the only one with an 'isVisible' param)
$.winFocus({
    blur: function(event) {
        console.log("Blur\t\t", event);
    },
    focus: function(event) {
        console.log("Focus\t\t", event);
    }
});

//  OR First method becoms a "blur", second method becoms "focus"!
$.winFocus(function(event) {
    console.log("Blur\t\t", event);
},
function(event) {
    console.log("Focus\t\t", event);
});

/* Begin Plugin */ ;;(function($){$.winFocus||($.extend({winFocus:function(){var a=!0,b=[];$(document).data("winFocus")||$(document).data("winFocus",$.winFocus.init());for(x in arguments)"object"==typeof arguments[x]?(arguments[x].blur&&$.winFocus.methods.blur.push(arguments[x].blur),arguments[x].focus&&$.winFocus.methods.focus.push(arguments[x].focus),arguments[x].blurFocus&&$.winFocus.methods.blurFocus.push(arguments[x].blurFocus),arguments[x].initRun&&(a=arguments[x].initRun)):"function"==typeof arguments[x]?b.push(arguments[x]): "boolean"==typeof arguments[x]&&(a=arguments[x]);b&&(1==b.length?$.winFocus.methods.blurFocus.push(b[0]):($.winFocus.methods.blur.push(b[0]),$.winFocus.methods.focus.push(b[1])));if(a)$.winFocus.methods.onChange()}}),$.winFocus.init=function(){$.winFocus.props.hidden in document?document.addEventListener("visibilitychange",$.winFocus.methods.onChange):($.winFocus.props.hidden="mozHidden")in document?document.addEventListener("mozvisibilitychange",$.winFocus.methods.onChange):($.winFocus.props.hidden= "webkitHidden")in document?document.addEventListener("webkitvisibilitychange",$.winFocus.methods.onChange):($.winFocus.props.hidden="msHidden")in document?document.addEventListener("msvisibilitychange",$.winFocus.methods.onChange):($.winFocus.props.hidden="onfocusin")in document?document.onfocusin=document.onfocusout=$.winFocus.methods.onChange:window.onpageshow=window.onpagehide=window.onfocus=window.onblur=$.winFocus.methods.onChange;return $.winFocus},$.winFocus.methods={blurFocus:[],blur:[],focus:[], exeCB:function(a){$.winFocus.methods.blurFocus&&$.each($.winFocus.methods.blurFocus,function(b,c){this.apply($.winFocus,[a,!a.hidden])});a.hidden&&$.winFocus.methods.blur&&$.each($.winFocus.methods.blur,function(b,c){this.apply($.winFocus,[a])});!a.hidden&&$.winFocus.methods.focus&&$.each($.winFocus.methods.focus,function(b,c){this.apply($.winFocus,[a])})},onChange:function(a){var b={focus:!1,focusin:!1,pageshow:!1,blur:!0,focusout:!0,pagehide:!0};if(a=a||window.event)a.hidden=a.type in b?b[a.type]: document[$.winFocus.props.hidden],$(window).data("visible",!a.hidden),$.winFocus.methods.exeCB(a);else try{$.winFocus.methods.onChange.call(document,new Event("visibilitychange"))}catch(c){}}},$.winFocus.props={hidden:"hidden"})})(jQuery); /* End Plugin */ // Simple example $(function() { $.winFocus(function(event, isVisible) { $('td tbody').empty(); $.each(event, function(i) { $('td tbody').append( $('<tr />').append( $('<th />', { text: i }), $('<td />', { text: this.toString() }) ) ) }); if (isVisible) $("#isVisible").stop().delay(100).fadeOut('fast', function(e) { $('body').addClass('visible'); $(this).stop().text('TRUE').fadeIn('slow'); }); else { $('body').removeClass('visible'); $("#isVisible").text('FALSE'); } }); }) body { background: #AAF; } table { width: 100%; } table table { border-collapse: collapse; margin: 0 auto; width: auto; } tbody > tr > th { text-align: right; } td { width: 50%; } th, td { padding: .1em .5em; } td th, td td { border: 1px solid; } .visible { background: #FFA; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <h3>See Console for Event Object Returned</h3> <table> <tr> <th><p>Is Visible?</p></th> <td><p id="isVisible">TRUE</p></td> </tr> <tr> <td colspan="2"> <table> <thead> <tr> <th colspan="2">Event Data <span style="font-size: .8em;">{ See Console for More Details }</span></th> </tr> </thead> <tbody></tbody> </table> </td> </tr> </table>