【问题标题】:Check if window has focus检查窗口是否有焦点
【发布时间】:2013-06-30 10:11:57
【问题描述】:

我需要检查用户是否有焦点窗口,我目前正在这样做:

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

每当我需要检查用户是否有焦点窗口时,我只需执行if(isonfocus==true)

问题:如果用户在页面加载之前失去焦点,即使我这样做了 if(isonfocus==true) 它将返回 true,即使窗口不在焦点上,并且将 var 定义为 false var isonfocus=false; 将执行相反的操作。

有人可以帮助我吗?谢谢。

更新
想象一个 PTC(付费点击)网站,当您点击广告进行查看时,大多数网站会验证用户是否真正看到广告商网站(有焦点)或没有(失去焦点)。
这与我需要的类似,我需要一种方法来验证用户是否将窗口(包含 iframe)放在焦点上。
为了获得焦点,用户可以单击 iframe、文档或选项卡。
请注意,这需要适用于所有主流浏览器。

【问题讨论】:

标签: javascript jquery


【解决方案1】:

为什么不使用hasFocus 方法,例如

if (document.hasFocus()) {
    ...
}

如果您还需要处理 iframe 的问题,那么您的支票就变成了或者,例如

function isFocused() {
    return document.hasFocus() || document.getElementById('iframe').contentWindow.document.hasFocus();
}

【讨论】:

  • 我需要检查窗口是否有焦点,而不是文档。
  • @user2536244 文档声明“布尔值指示文档或文档内部的任何元素是否具有焦点” - 这适用于窗口也很专注。
  • 如果窗口有 iframe(点击 iframe 获得焦点),它似乎不起作用。
  • 这听起来对我来说是正确的,因为 iframe 应该表现为一个单独的窗口。
  • 使用 Chrome 时,它​​给了我两个错误:阻止了原点为“xxx”的帧访问原点为“yyy”的帧。协议、域和端口必须匹配。 TypeError:无法调用未定义的方法“hasFocus”
【解决方案2】:

您可以使用document.visibilityState 了解页面是否处于焦点。

【讨论】:

  • 不幸的是,这不是真的。 visibilityStatevisible 除非页面完全脱离屏幕,因为窗口已最小化,用户在同一窗口中的不同选项卡中,或者显示关闭。仅仅被另一个窗口遮挡仍然算作“可见”。
  • 就我而言,这正是我所需要的,老实说,当我阅读上面的问题时,我相信这是正确的答案,应该这样标记。 javascript没有办法查看它是否被另一个窗口遮挡。
  • 如果您想知道浏览器是否是活动/聚焦窗口,请参阅下面的答案
  • 看起来document.hasFocus() 可以在 Windows 上运行,但如果您切换到另一个应用程序,则无法在 Android 上运行 - 页面仍然认为它是焦点。所以我不得不使用document.visibilityState == "visible",它在我的情况下都运行良好。您的可能会有所不同。
【解决方案3】:
var has_focus = true;

function loading_time() {
    $(":focus").each(function() {
      if($(this).attr("id")=="iframeID") has_focus = true;
    });

    if(has_focus==true) alert('page has focus');
    else alert('page has not focus');

    setTimeout("loading_time()", 2000);
}

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

$(window).load(function(){
    setTimeout("loading_time()", 2000);
});

为了提高效率,您需要var has_focus = false; 并让用户点击页面上的某处。

【讨论】:

    【解决方案4】:

    跨浏览器 jQuery 解决方案! 以下插件将通过您对各种版本的 IE、Chrome、Firefox、Safari 等的标准测试。并相应地建立您声明的方法。它还处理以下问题:

    • 计时器!哇!
    • onblur|.blur/onfocus|.focus "重复" 调用
    • 通过选择备用应用程序(如 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);
    });
    

    New&improvedversion,madeforbothvanillaandjQueryfoundhere!


    /*    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>

    【讨论】:

    • 它无法检测用户是否使用 alt-tab 切换了窗口。
    【解决方案5】:

    如果您不关心 Opera 支持,使用 document.hasFocus() 方法可能会获得更好的结果。有关更多信息,请参阅here

    【讨论】:

    • 我需要检查窗口是否有焦点,而不是文档。
    • 对于 Opera 你应该写一个hasHasFocus 函数:function hasHasFocus() { return typeof document.hasFocus === 'function'; } 我只是觉得这个名字很有趣。
    【解决方案6】:

    此主题中的信息太旧。 继续使用:document.hasFocus()。 现在它适用于您需要的所有浏览器。

    浏览器兼容性:https://developer.mozilla.org/en-US/docs/Web/API/Document/hasFocus#browser_compatibility

    【讨论】:

      【解决方案7】:

      如果用户的浏览器窗口已聚焦/处于活动状态,但刚刚单击了刷新按钮(或 url 栏等),document.hasFocus() 将告诉您该窗口未处于活动状态。

      但是,您可以调用window.focus() 并查看focus 事件是否实际被触发。如果是,则浏览器仍处于焦点/活动状态。

      const windowHasFocus = function () {
        if (document.hasFocus()) return true
        let hasFocus = false
      
        window.addEventListener('focus', function () {
          hasFocus = true
        })
        window.focus()
      
        return hasFocus
      }
      
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-08
      • 1970-01-01
      • 2020-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多