Javascript 检测浏览器标签是否有焦点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7389328/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detect If Browser Tab Has Focus
提问by Fenton
Is there a reliable cross-browser way to detect that a tab has focus.
是否有可靠的跨浏览器方式来检测选项卡是否具有焦点。
The scenario is that we have an application that polls regularly for stock prices, and if the page doesn't have focus we could stop the polling and save everyone the traffic noise, especially as people are fans of opening several tabs with different portfolios.
场景是我们有一个应用程序定期轮询股票价格,如果页面没有焦点,我们可以停止轮询并为每个人节省交通噪音,特别是当人们喜欢打开具有不同投资组合的多个标签时。
Is window.onblur
and window.onfocus
an option for this?
是window.onblur
和window.onfocus
这个选项?
采纳答案by Ryan Wright
Yes, window.onfocus
and window.onblur
should work for your scenario:
是的,window.onfocus
并且window.onblur
应该为您的方案的工作:
http://www.thefutureoftheweb.com/blog/detect-browser-window-focus
http://www.thefutureoftheweb.com/blog/detect-browser-window-focus
回答by Zirak
Important Edit:This answer is outdated. Since writing it, the Visibility API (mdn, example, spec) has been introduced. It is the better way to solve this problem.
重要编辑:此答案已过时。自从编写它以来,已经引入了 Visibility API(mdn、example、spec)。这是解决这个问题的更好方法。
var focused = true;
window.onfocus = function() {
focused = true;
};
window.onblur = function() {
focused = false;
};
AFAIK, focus
and blur
are all supported on...everything. (see http://www.quirksmode.org/dom/events/index.html)
AFAIK,focus
并且blur
都支持......一切。(见http://www.quirksmode.org/dom/events/index.html)
回答by Ilija
While searching about this problem, I found a recommendation that Page Visibility APIshould be used. Most modern browsers support this API according to Can I Use: http://caniuse.com/#feat=pagevisibility.
在搜索此问题时,我发现应该使用Page Visibility API的建议。根据 Can I Use:http: //caniuse.com/#feat=pagevisibility ,大多数现代浏览器都支持此 API 。
Here's a working example (derived from this snippet):
这是一个工作示例(源自此代码段):
$(document).ready(function() {
var hidden, visibilityState, visibilityChange;
if (typeof document.hidden !== "undefined") {
hidden = "hidden", visibilityChange = "visibilitychange", visibilityState = "visibilityState";
} else if (typeof document.msHidden !== "undefined") {
hidden = "msHidden", visibilityChange = "msvisibilitychange", visibilityState = "msVisibilityState";
}
var document_hidden = document[hidden];
document.addEventListener(visibilityChange, function() {
if(document_hidden != document[hidden]) {
if(document[hidden]) {
// Document hidden
} else {
// Document shown
}
document_hidden = document[hidden];
}
});
});
Update:The example above used to have prefixed properties for Gecko and WebKit browsers, but I removed that implementation because these browsers have been offering Page Visibility API without a prefix for a while now. I kept Microsoft specific prefix in order to stay compatible with IE10.
更新:上面的例子曾经有 Gecko 和 WebKit 浏览器的前缀属性,但我删除了这个实现,因为这些浏览器已经提供了一段时间没有前缀的页面可见性 API。为了与 IE10 保持兼容,我保留了 Microsoft 特定的前缀。
回答by aleclarson
Surprising to see nobody mentioned document.hasFocus
令人惊讶的是没有人提到 document.hasFocus
if (document.hasFocus()) console.log('Tab is active')
回答by Brian Glaz
Yes those should work for you. You just reminded me of this link I came across that exploits those techniques. interesting read
是的,那些应该适合你。您只是让我想起了我遇到的利用这些技术的链接。有趣的阅读
回答by confile
I would do it this way (Reference http://www.w3.org/TR/page-visibility/):
我会这样做(参考http://www.w3.org/TR/page-visibility/):
window.onload = function() {
// check the visiblility of the page
var hidden, visibilityState, visibilityChange;
if (typeof document.hidden !== "undefined") {
hidden = "hidden", visibilityChange = "visibilitychange", visibilityState = "visibilityState";
}
else if (typeof document.mozHidden !== "undefined") {
hidden = "mozHidden", visibilityChange = "mozvisibilitychange", visibilityState = "mozVisibilityState";
}
else if (typeof document.msHidden !== "undefined") {
hidden = "msHidden", visibilityChange = "msvisibilitychange", visibilityState = "msVisibilityState";
}
else if (typeof document.webkitHidden !== "undefined") {
hidden = "webkitHidden", visibilityChange = "webkitvisibilitychange", visibilityState = "webkitVisibilityState";
}
if (typeof document.addEventListener === "undefined" || typeof hidden === "undefined") {
// not supported
}
else {
document.addEventListener(visibilityChange, function() {
console.log("hidden: " + document[hidden]);
console.log(document[visibilityState]);
switch (document[visibilityState]) {
case "visible":
// visible
break;
case "hidden":
// hidden
break;
}
}, false);
}
if (document[visibilityState] === "visible") {
// visible
}
};
回答by SpYk3HH
Cross Browser jQuery Solution!Raw available at GitHub
跨浏览器 jQuery 解决方案!在GitHub 上提供原始数据
Fun & Easy to Use!
有趣且易于使用!
The following plugin will go through your standard test for various versions of IE, Chrome, Firefox, Safari, etc.. and establish your declared methods accordingly. It also deals with issues such as:
以下插件将通过您对各种版本的 IE、Chrome、Firefox、Safari 等的标准测试,并相应地建立您声明的方法。它还处理以下问题:
- onblur|.blur/onfocus|.focus "duplicate" calls
- window losing focus through selection of alternate app, like word
- This tends to be undesirable simply because, if you have a bank page open, and it's onblurevent tells it to mask the page, then if you open calculator, you can't see the page anymore!
- Not triggering on page load
- onblur|.blur/onfocus|.focus “重复”调用
- 窗口通过选择替代应用程序失去焦点,例如 word
- 这往往是不可取的,因为,如果您打开了一个银行页面,并且它的onblur事件告诉它屏蔽页面,那么如果您打开计算器,您将无法再看到该页面!
- 页面加载时不触发
Use is as simple as: Scroll Down to 'Run Snippet'
使用很简单:向下滚动到“运行代码段”
$.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>