我有JavaScript,它周期性地执行活动。当用户没有在看站点时(例如,窗口或选项卡没有焦点),最好不要运行。
是否有一种方法可以使用JavaScript来做到这一点?
我的参考点:如果你正在使用的窗口不活跃,Gmail聊天就会播放声音。
我有JavaScript,它周期性地执行活动。当用户没有在看站点时(例如,窗口或选项卡没有焦点),最好不要运行。
是否有一种方法可以使用JavaScript来做到这一点?
我的参考点:如果你正在使用的窗口不活跃,Gmail聊天就会播放声音。
当前回答
这是根据安迪?
这将执行一个任务,例如每30秒刷新一次页面, 但前提是页面是可见的和集中的。
如果无法检测到可见性,则只使用焦点。
如果用户聚焦页面,那么它将立即更新
页面直到ajax调用后30秒才会再次更新
var windowFocused = true;
var timeOut2 = null;
$(function(){
$.ajaxSetup ({
cache: false
});
$("#content").ajaxComplete(function(event,request, settings){
set_refresh_page(); // ajax call has just been made, so page doesn't need updating again for 30 seconds
});
// check visibility and focus of window, so as not to keep updating unnecessarily
(function() {
var hidden, change, vis = {
hidden: "visibilitychange",
mozHidden: "mozvisibilitychange",
webkitHidden: "webkitvisibilitychange",
msHidden: "msvisibilitychange",
oHidden: "ovisibilitychange" /* not currently supported */
};
for (hidden in vis) {
if (vis.hasOwnProperty(hidden) && hidden in document) {
change = vis[hidden];
break;
}
}
document.body.className="visible";
if (change){ // this will check the tab visibility instead of window focus
document.addEventListener(change, onchange,false);
}
if(navigator.appName == "Microsoft Internet Explorer")
window.onfocus = document.onfocusin = document.onfocusout = onchangeFocus
else
window.onfocus = window.onblur = onchangeFocus;
function onchangeFocus(evt){
evt = evt || window.event;
if (evt.type == "focus" || evt.type == "focusin"){
windowFocused=true;
}
else if (evt.type == "blur" || evt.type == "focusout"){
windowFocused=false;
}
if (evt.type == "focus"){
update_page(); // only update using window.onfocus, because document.onfocusin can trigger on every click
}
}
function onchange () {
document.body.className = this[hidden] ? "hidden" : "visible";
update_page();
}
function update_page(){
if(windowFocused&&(document.body.className=="visible")){
set_refresh_page(1000);
}
}
})();
set_refresh_page();
})
function get_date_time_string(){
var d = new Date();
var dT = [];
dT.push(d.getDate());
dT.push(d.getMonth())
dT.push(d.getFullYear());
dT.push(d.getHours());
dT.push(d.getMinutes());
dT.push(d.getSeconds());
dT.push(d.getMilliseconds());
return dT.join('_');
}
function do_refresh_page(){
// do tasks here
// e.g. some ajax call to update part of the page.
// (date time parameter will probably force the server not to cache)
// $.ajax({
// type: "POST",
// url: "someUrl.php",
// data: "t=" + get_date_time_string()+"&task=update",
// success: function(html){
// $('#content').html(html);
// }
// });
}
function set_refresh_page(interval){
interval = typeof interval !== 'undefined' ? interval : 30000; // default time = 30 seconds
if(timeOut2 != null) clearTimeout(timeOut2);
timeOut2 = setTimeout(function(){
if((document.body.className=="visible")&&windowFocused){
do_refresh_page();
}
set_refresh_page();
}, interval);
}
其他回答
我会使用jQuery,因为这样你所要做的就是:
$(window).blur(function(){
//your code here
});
$(window).focus(function(){
//your code
});
至少对我有用。
我的代码
let browser_active = ((typeof document.hasFocus != 'undefined' ? document.hasFocus() : 1) ? 1 : 0);
if (!browser_active) {
// active
}
U可以使用:
(function () {
var requiredResolution = 10; // ms
var checkInterval = 1000; // ms
var tolerance = 20; // percent
var counter = 0;
var expected = checkInterval / requiredResolution;
//console.log('expected:', expected);
window.setInterval(function () {
counter++;
}, requiredResolution);
window.setInterval(function () {
var deviation = 100 * Math.abs(1 - counter / expected);
// console.log('is:', counter, '(off by', deviation , '%)');
if (deviation > tolerance) {
console.warn('Timer resolution not sufficient!');
}
counter = 0;
}, checkInterval);
})();
我为我的应用程序创建了一个Comet Chat,当我收到来自我使用的另一个用户的消息时:
if(new_message){
if(!document.hasFocus()){
audio.play();
document.title="Have new messages";
}
else{
audio.stop();
document.title="Application Name";
}
}
这真的很棘手。考虑到以下要求,似乎没有解决方案。
该页包括您无法控制的iframe 您希望跟踪可见性状态更改,而不管更改是由选项卡更改(ctrl+ TAB)或窗口更改(alt+ TAB)触发的。
这是因为:
页面可视性API可以可靠地告诉您一个选项卡更改(即使使用iframes),但它不能告诉您用户何时更改了窗口。 监听窗口模糊/聚焦事件可以检测alt+选项卡和ctrl+选项卡,只要iframe没有焦点。
考虑到这些限制,可以实现一个组合的解决方案 -页面可见性API -窗口模糊/聚焦 ——document.activeElement
能够:
1)当父页有焦点时按ctrl+tab: YES 2) iframe有焦点时按ctrl+tab: YES 3)当父页有焦点时,alt+tab: YES 4)当iframe有focus时,alt+tab: NO <——bummer
当iframe有焦点时,你的模糊/焦点事件根本不会被调用,页面可视性API也不会在alt+选项卡上触发。
我以@AndyE的解决方案为基础,在这里实现了这个(几乎很好的)解决方案: https://dl.dropboxusercontent.com/u/2683925/estante-components/visibility_test1.html (对不起,我有一些麻烦与JSFiddle)。
这也可以在Github上找到:https://github.com/qmagico/estante-components
这适用于铬/铬。 它在firefox上工作,除了它不加载iframe内容(知道为什么吗?)
无论如何,为了解决最后一个问题(4),你能做的唯一方法是监听iframe上的模糊/聚焦事件。 如果你对iframe有一些控制,你可以使用postMessage API来做到这一点。
https://dl.dropboxusercontent.com/u/2683925/estante-components/visibility_test2.html
我还没有在足够多的浏览器上测试这个功能。 如果你能找到更多关于哪里不行的信息,请在下面的评论中告诉我。