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

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

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


当前回答

在HTML 5中,你也可以使用:

onpageshow:当窗口变得可见时运行的脚本 onpagehide:当窗口隐藏时运行的脚本

See:

https://developer.mozilla.org/en-US/docs/Web/Events/pageshow https://developer.mozilla.org/en-US/docs/Web/Events/pagehide

其他回答

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

http://jsfiddle.net/ARTsinn/JTxQY/

对于没有jQuery的解决方案,请参阅Visibility.js,它提供了关于三个页面状态的信息

visible    ... page is visible
hidden     ... page is not visible
prerender  ... page is being prerendered by the browser

以及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();
});

旧版浏览器(IE < 10;iOS < 7)也可用

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

更改制表符时 更改窗口时(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...")
  }
}

简单的/立即检查:

if(document.hidden) {
  // do something
}

可见性变化事件:

document.addEventListener("visibilitychange", function() {
  console.log(document.visibilityState); // "hidden" or "visible"
}, false);

基于承诺的事件:

// An `await`able function that resolves when page visibility changes:
function visibilityChange(state="") {
  return new Promise(resolve => {
    document.addEventListener("visibilitychange", function() {
      if(!state || document.visibilityState === state) { 
        resolve(document.visibilityState);
        document.removeEventListener("visibilitychange", arguments.callee);
      }
    });
  });
}

// Use it like this:
await visibilityChange();
console.log(document.visibilityState);

// Or wait for page to become...
await visibilityChange("visible");
await visibilityChange("hidden");

(注:后两个解是我加到这个答案里的,因为这个问题现在已经结束了,我不能加我自己的答案。以防有人认为我抄袭了那篇文章而没有注明出处。)

这是根据安迪?

这将执行一个任务,例如每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);
}