我的JavaScript会定期进行活动。当用户不查看站点时(即窗口或选项卡没有焦点),最好不要运行。
有没有办法使用JavaScript做到这一点?
我的参考点:如果您使用的窗口未激活,则Gmail聊天会播放声音。
我的JavaScript会定期进行活动。当用户不查看站点时(即窗口或选项卡没有焦点),最好不要运行。
有没有办法使用JavaScript做到这一点?
我的参考点:如果您使用的窗口未激活,则Gmail聊天会播放声音。
Here is a solid, modern solution. (Short a sweet 👌🏽)
document.addEventListener("visibilitychange", () => {
console.log( document.hasFocus() )
})
This will setup a listener to trigger when any visibility event is fired which could be a focus or blur.
For a solution without jQuery check out Visibility.js which provides information about three page states
visible ... page is visible
hidden ... page is not visible
prerender ... page is being prerendered by the browser
and also convenience-wrappers for setInterval
/* Perform action every second if visible */
Visibility.every(1000, function () {
action();
});
/* Perform action every second if visible, every 60 sec if not visible */
Visibility.every(1000, 60*1000, function () {
action();
});
A fallback for older browsers (IE < 10; iOS < 7) is also available
在HTML 5中,您还可以使用:
onpageshow
:窗口可见时要运行的脚本onpagehide
:隐藏窗口时运行的脚本看到:
这对我适用于chrome 67,firefox 67,
if(!document.hasFocus()) {
// do stuff
}
var visibilityChange = (function (window) {
var inView = false;
return function (fn) {
window.onfocus = window.onblur = window.onpageshow = window.onpagehide = function (e) {
if ({focus:1, pageshow:1}[e.type]) {
if (inView) return;
fn("visible");
inView = true;
} else if (inView) {
fn("hidden");
inView = false;
}
};
};
}(this));
visibilityChange(function (state) {
console.log(state);
});
这真的很棘手。鉴于以下要求,似乎没有解决方案。
发生这种情况是因为:
鉴于这些限制,可以实现一个结合以下解决方案的解决方案-页面可见性API-窗口模糊/焦点-document.activeElement
能够:
当iframe具有焦点时,根本不会调用您的模糊/焦点事件,并且页面可见性API不会在alt + tab上触发。
我以@AndyE的解决方案为基础,并在此处实现了这个(几乎是很好的)解决方案:https : //dl.dropboxusercontent.com/u/2683925/estante-components/visibility_test1.html(对不起,我在JSFiddle上遇到了一些麻烦)。
这也可以在Github上获得:https : //github.com/qmagico/estante-components
这适用于铬/铬。除了不加载iframe内容(知道为什么?)以外,它在Firefox上都可以使用
无论如何,要解决最后一个问题(4),唯一的方法是在iframe上监听模糊/聚焦事件。如果您对iframe有所控制,则可以使用postMessage API来执行此操作。
https://dl.dropboxusercontent.com/u/2683925/estante-components/visibility_test2.html
我仍然没有在足够多的浏览器上对此进行测试。如果您可以找到有关此功能无效的更多信息,请在下面的评论中告诉我。
GitHub上有一个整洁的库:
https://github.com/serkanyersen/ifvisible.js
例:
// If page is visible right now
if( ifvisible.now() ){
// Display pop-up
openPopUp();
}
我已经在所有浏览器上测试了1.0.1版,并且可以确认该版本适用于:
...以及可能所有较新的版本。
不能与以下产品完全配合使用:
.now()
始终true
为我返回)我为我的应用创建了彗星聊天,当我收到其他用户的消息时,我使用:
if(new_message){
if(!document.hasFocus()){
audio.play();
document.title="Have new messages";
}
else{
audio.stop();
document.title="Application Name";
}
}
我将使用jQuery,因为那么您要做的就是:
$(window).blur(function(){
//your code here
});
$(window).focus(function(){
//your code
});
或者至少对我有用。
自从最初编写此答案以来,由于有了W3C ,新的规范已达到推荐状态。现在,页面可见性API(在MDN上)使我们能够更准确地检测页面何时向用户隐藏。
document.addEventListener("visibilitychange", onchange);
当前的浏览器支持:
以下代码会退回到不兼容浏览器中不太可靠的模糊/聚焦方法:
(function() {
var hidden = "hidden";
// Standards:
if (hidden in document)
document.addEventListener("visibilitychange", onchange);
else if ((hidden = "mozHidden") in document)
document.addEventListener("mozvisibilitychange", onchange);
else if ((hidden = "webkitHidden") in document)
document.addEventListener("webkitvisibilitychange", onchange);
else if ((hidden = "msHidden") in document)
document.addEventListener("msvisibilitychange", onchange);
// IE 9 and lower:
else if ("onfocusin" in document)
document.onfocusin = document.onfocusout = onchange;
// All others:
else
window.onpageshow = window.onpagehide
= window.onfocus = window.onblur = onchange;
function onchange (evt) {
var v = "visible", h = "hidden",
evtMap = {
focus:v, focusin:v, pageshow:v, blur:h, focusout:h, pagehide:h
};
evt = evt || window.event;
if (evt.type in evtMap)
document.body.className = evtMap[evt.type];
else
document.body.className = this[hidden] ? "hidden" : "visible";
}
// set the initial state (but only if browser supports the Page Visibility API)
if( document[hidden] !== undefined )
onchange({type: document[hidden] ? "blur" : "focus"});
})();
onfocusin
和IE 9及更低版本onfocusout
是必需的,而其他所有语言都使用onfocus
和onblur
(iOS除外,后者使用onpageshow
和)onpagehide
。
If you want to act on whole browser blur: As I commented, if browser loose focus none of the suggested events fire. My idea is to count up in a loop and reset the counter if an event fire. If the counter reach a limit I do a location.href to an other page. This also fire if you work on dev-tools.
This is a draft successful tested on FF.