可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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?
回答1:
Yes, window.onfocus
and window.onblur
should work for your scenario:
http://www.thefutureoftheweb.com/blog/detect-browser-window-focus
回答2:
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.
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 )
回答3:
While searching about this problem, I found a recommendation that Page Visibility API should be used. Most modern browsers support this API according to Can I Use: http://caniuse.com/#feat=pagevisibility.
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.
回答4:
Yes those should work for you. You just reminded me of this link I came across that exploits those techniques. interesting read
回答5:
Surprising to see nobody mentioned document.hasFocus
if (document.hasFocus()) console.log(\'Tab is active\')
MDN has more information.
回答6:
I would do it this way (Reference 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
}
};
回答7:
Cross Browser jQuery Solution! Raw available at 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:
- 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 onblur event tells it to mask the page, then if you open calculator, you can\'t see the page anymore!
- Not triggering on page load
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>