我有JavaScript,它周期性地执行活动。当用户没有在看站点时(例如,窗口或选项卡没有焦点),最好不要运行。
是否有一种方法可以使用JavaScript来做到这一点?
我的参考点:如果你正在使用的窗口不活跃,Gmail聊天就会播放声音。
我有JavaScript,它周期性地执行活动。当用户没有在看站点时(例如,窗口或选项卡没有焦点),最好不要运行。
是否有一种方法可以使用JavaScript来做到这一点?
我的参考点:如果你正在使用的窗口不活跃,Gmail聊天就会播放声音。
当前回答
我重读了@daniel-buckmaster的版本 我没有做多次尝试,但是,代码对我来说似乎更优雅…
// on-visibility-change.js v1.0.1, based on https://stackoverflow.com/questions/1060008/is-there-a-way-to-detect-if-a-browser-window-is-not-currently-active#38710376
function onVisibilityChange(callback) {
let d = document;
let visible = true;
let prefix;
if ('hidden' in d) {
prefix = 'h';
} else if ('webkitHidden' in d) {
prefix = 'webkitH';
} else if ('mozHidden' in d) {
prefix = 'mozH';
} else if ('msHidden' in d) {
prefix = 'msH';
} else if ('onfocusin' in d) { // ie 9 and lower
d.onfocusin = focused;
d.onfocusout = unfocused;
} else { // others
window.onpageshow = window.onfocus = focused;
window.onpagehide = window.onblur = unfocused;
};
if (prefix) {
visible = !d[prefix + 'idden'];
d.addEventListener(prefix.substring(0, prefix.length - 1) + 'visibilitychange', function() {
(d[prefix + 'idden'] ? unfocused : focused)();
});
};
function focused() {
if (!visible) {
callback(visible = true);
};
};
function unfocused() {
if (visible) {
callback(visible = false);
};
};
};
其他回答
这对我很有效
document.addEventListener("visibilitychange", function() {
document.title = document.hidden ? "I'm away" : "I'm here";
});
演示:https://iamsahilralkar.github.io/document-hidden-demo/
我开始使用社区维基答案,但意识到它没有检测alt-tab事件在Chrome。这是因为它使用了第一个可用的事件源,在这种情况下,它是页面可见性API,在Chrome中似乎不跟踪alt-tab。
我决定稍微修改一下脚本,以跟踪页面焦点更改的所有可能事件。这是一个你可以放入的函数:
function onVisibilityChange(callback) {
var visible = true;
if (!callback) {
throw new Error('no callback given');
}
function focused() {
if (!visible) {
callback(visible = true);
}
}
function unfocused() {
if (visible) {
callback(visible = false);
}
}
// Standards:
if ('hidden' in document) {
visible = !document.hidden;
document.addEventListener('visibilitychange',
function() {(document.hidden ? unfocused : focused)()});
}
if ('mozHidden' in document) {
visible = !document.mozHidden;
document.addEventListener('mozvisibilitychange',
function() {(document.mozHidden ? unfocused : focused)()});
}
if ('webkitHidden' in document) {
visible = !document.webkitHidden;
document.addEventListener('webkitvisibilitychange',
function() {(document.webkitHidden ? unfocused : focused)()});
}
if ('msHidden' in document) {
visible = !document.msHidden;
document.addEventListener('msvisibilitychange',
function() {(document.msHidden ? unfocused : focused)()});
}
// IE 9 and lower:
if ('onfocusin' in document) {
document.onfocusin = focused;
document.onfocusout = unfocused;
}
// All others:
window.onpageshow = window.onfocus = focused;
window.onpagehide = window.onblur = unfocused;
};
像这样使用它:
onVisibilityChange(function(visible) {
console.log('the page is now', visible ? 'focused' : 'unfocused');
});
该版本监听所有不同的可见性事件,并在其中任何事件导致更改时触发回调。焦点处理程序和非焦点处理程序确保如果多个api捕捉到相同的可见性更改,不会多次调用回调。
从最初编写这个答案开始,由于W3C,一个新的规范已经达到了推荐状态。页面可见性API(在MDN上)现在允许我们更准确地检测页面何时对用户隐藏。
document.addEventListener("visibilitychange", onchange);
当前浏览器支持:
铬13 + Internet Explorer 10+ Firefox 10 + Opera 12.10+[阅读笔记]
下面的代码在不兼容的浏览器中退回到不太可靠的模糊/聚焦方法:
(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"});
})();
ie9及以下版本需要onfocusin和onfocusout,而所有其他都使用onfocus和onblur,除了iOS,它使用onpageshow和onpagehide。
稍微复杂一点的方法是使用setInterval()检查鼠标位置并与上次检查进行比较。如果鼠标在一段时间内没有移动,则用户可能处于空闲状态。
这有一个额外的好处,可以告诉用户是否空闲,而不仅仅是检查窗口是否处于活动状态。
正如许多人指出的那样,这并不总是一种检查用户或浏览器窗口是否空闲的好方法,因为用户甚至可能没有使用鼠标或正在观看视频或类似的内容。我只是建议一种检查空闲状态的方法。
在GitHub上有一个简洁的库:
https://github.com/serkanyersen/ifvisible.js
例子:
// If page is visible right now
if( ifvisible.now() ){
// Display pop-up
openPopUp();
}
我已经在我拥有的所有浏览器上测试了1.0.1版本,并可以确认它适用于:
的问世,IE9 FF 26.0 Chrome 34.0
... 可能还有所有更新的版本。
不完全适用于:
IE8 -总是指示标签/窗口当前是活跃的(.now()总是为我返回true)