我有JavaScript,它周期性地执行活动。当用户没有在看站点时(例如,窗口或选项卡没有焦点),最好不要运行。

是否有一种方法可以使用JavaScript来做到这一点?

我的参考点:如果你正在使用的窗口不活跃,Gmail聊天就会播放声音。


当前回答

这适用于所有现代浏览器:

更改制表符时 更改窗口时(Alt+Tab) 当从任务栏最大化另一个程序时

var eventName;
var visible = true;
var propName = "hidden";
if (propName in document) eventName = "visibilitychange";
else if ((propName = "msHidden") in document) eventName = "msvisibilitychange";
else if ((propName = "mozHidden") in document) eventName = "mozvisibilitychange";
else if ((propName = "webkitHidden") in document) eventName = "webkitvisibilitychange";
if (eventName) document.addEventListener(eventName, handleChange);

if ("onfocusin" in document) document.onfocusin = document.onfocusout = handleChange; //IE 9
window.onpageshow = window.onpagehide = window.onfocus = window.onblur = handleChange;// Changing tab with alt+tab

// Initialize state if Page Visibility API is supported
if (document[propName] !== undefined) handleChange({ type: document[propName] ? "blur" : "focus" });

function handleChange(evt) {
  evt = evt || window.event;
  if (visible && (["blur", "focusout", "pagehide"].includes(evt.type) || (this && this[propName]))){
    visible = false;
    console.log("Out...")
  }
  else if (!visible && (["focus", "focusin", "pageshow"].includes(evt.type) || (this && !this[propName]))){
    visible = true;
    console.log("In...")
  }
}

其他回答

我会使用jQuery,因为这样你所要做的就是:

$(window).blur(function(){
  //your code here
});
$(window).focus(function(){
  //your code
});

至少对我有用。

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);

})();

如果你想对整个浏览器模糊: 正如我所评论的,如果浏览器失去焦点,建议的事件都不会触发。我的想法是在循环中计数,并在事件发生时重置计数器。如果计数器达到限制,我做一个位置。请转到另一页。如果你在开发工具上工作,这也会触发。

var iput=document.getElementById("hiddenInput");
   ,count=1
   ;
function check(){
         count++;
         if(count%2===0){
           iput.focus();
         }
         else{
           iput.blur();
         }
         iput.value=count;  
         if(count>3){
           location.href="http://Nirwana.com";
         }              
         setTimeout(function(){check()},1000);
}   
iput.onblur=function(){count=1}
iput.onfocus=function(){count=1}
check();

这是在FF上成功测试的草稿。

从最初编写这个答案开始,由于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。

我为我的应用程序创建了一个Comet Chat,当我收到来自我使用的另一个用户的消息时:

if(new_message){
    if(!document.hasFocus()){
        audio.play();
        document.title="Have new messages";
    }
    else{
        audio.stop();
        document.title="Application Name";
    } 
}