首页 > JavaScript > JavaScript 有没有办法检测浏览器窗口当前是否处于活动状态?

JavaScript 有没有办法检测浏览器窗口当前是否处于活动状态?

上一篇 下一篇

我有定期做活动的JavaScript。当用户不查看站点(即窗口或选项卡没有焦点)时,最好不要运行。

有没有办法使用 JavaScript 来做到这一点?

我的参考点:如果您使用的窗口未处于活动状态,Gmail 聊天会播放声音。

分割线

网友回答:

自从最初编写这个答案以来,由于W3C,一个新的规范已经达到了推荐状态。页面可见性API(在MDN上)现在允许我们更准确地检测页面何时对用户隐藏。

document.addEventListener("visibilitychange", onchange);

当前浏览器支持:

  • 铬 13+
  • IE浏览器 10+
  • 火狐 10+
  • 歌剧 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"});
})();

onfocusin并且对于 IE 9 及更低版本是必需的,而所有其他版本都使用 和 ,但 iOS 除外,它使用 和 。onfocusoutonfocusonbluronpageshowonpagehide

分割线

网友回答:

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

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

或者至少它对我有用。

分割线

网友回答:

有 3 种典型的方法用于确定用户是否可以看到 HTML 页面,但没有一种完美运行:

  • W3C Page Visibility API 应该这样做(自 Firefox 10、MSIE 10、Chrome 13 以来一直支持)。但是,此 API 仅在浏览器选项卡被完全覆盖时引发事件(例如,当用户从一个选项卡更改为另一个选项卡时)。当无法 100% 准确确定可见性时,API 不会引发事件(例如,使用 Alt+Tab 切换到另一个应用程序)。
  • 使用基于焦点/模糊的方法会产生很多误报。例如,如果用户在浏览器窗口顶部显示一个较小的窗口,则浏览器窗口将失去焦点(升高),但用户仍然能够看到它(因此它仍然需要刷新)。另请参阅 http://javascript.info/tutorial/focusonblur
  • 依靠用户活动(鼠标移动、单击、键入键)也会给您带来很多误报。考虑与上述相同的情况,或者用户观看视频。

为了改善上述不完美行为,我结合使用了 3 种方法:W3C 可见性 API,然后是聚焦/模糊和用户活动方法,以降低误报率。这允许管理以下事件:

  • 将浏览器选项卡更改为另一个选项卡(100% 准确,这要归功于 W3C 页面可见性 API)
  • 页面可能被另一个窗口隐藏,例如由于 Alt+Tab(概率 = 不是 100% 准确)
  • 用户的注意力可能不集中在HTML页面上(概率=不是100%准确)

这是它的工作原理:当文档失去焦点时,将监视文档上的用户活动(例如鼠标移动),以确定窗口是否可见。页面可见性概率与页面上上次用户活动的时间成反比:如果用户长时间没有在文档上进行任何活动,则页面很可能不可见。下面的代码模仿 W3C 页面可见性 API:它的行为方式相同,但误报率很小。它具有多浏览器的优势(在Firefox 5,Firefox 10,MSIE 9,MSIE 7,Safari 5,Chrome 9上测试)。


    <div id="x"></div>
     
    <script>
    /**
    Registers the handler to the event for the given object.
    @param obj the object which will raise the event
    @param evType the event type: click, keypress, mouseover, ...
    @param fn the event handler function
    @param isCapturing set the event mode (true = capturing event, false = bubbling event)
    @return true if the event handler has been attached correctly
    */
    function addEvent(obj, evType, fn, isCapturing){
      if (isCapturing==null) isCapturing=false; 
      if (obj.addEventListener){
        // Firefox
        obj.addEventListener(evType, fn, isCapturing);
        return true;
      } else if (obj.attachEvent){
        // MSIE
        var r = obj.attachEvent('on'+evType, fn);
        return r;
      } else {
        return false;
      }
    }
     
    // register to the potential page visibility change
    addEvent(document, "potentialvisilitychange", function(event) {
      document.getElementById("x").innerHTML+="potentialVisilityChange: potentialHidden="+document.potentialHidden+", document.potentiallyHiddenSince="+document.potentiallyHiddenSince+" s<br>";
    });
     
    // register to the W3C Page Visibility API
    var hidden=null;
    var visibilityChange=null;
    if (typeof document.mozHidden !== "undefined") {
      hidden="mozHidden";
      visibilityChange="mozvisibilitychange";
    } else if (typeof document.msHidden !== "undefined") {
      hidden="msHidden";
      visibilityChange="msvisibilitychange";
    } else if (typeof document.webkitHidden!=="undefined") {
      hidden="webkitHidden";
      visibilityChange="webkitvisibilitychange";
    } else if (typeof document.hidden !=="hidden") {
      hidden="hidden";
      visibilityChange="visibilitychange";
    }
    if (hidden!=null && visibilityChange!=null) {
      addEvent(document, visibilityChange, function(event) {
        document.getElementById("x").innerHTML+=visibilityChange+": "+hidden+"="+document[hidden]+"<br>";
      });
    }
     
     
    var potentialPageVisibility = {
      pageVisibilityChangeThreshold:3*3600, // in seconds
      init:function() {
        function setAsNotHidden() {
          var dispatchEventRequired=document.potentialHidden;
          document.potentialHidden=false;
          document.potentiallyHiddenSince=0;
          if (dispatchEventRequired) dispatchPageVisibilityChangeEvent();
        }
     
        function initPotentiallyHiddenDetection() {
          if (!hasFocusLocal) {
            // the window does not has the focus => check for  user activity in the window
            lastActionDate=new Date();
            if (timeoutHandler!=null) {
              clearTimeout(timeoutHandler);
            }
            timeoutHandler = setTimeout(checkPageVisibility, potentialPageVisibility.pageVisibilityChangeThreshold*1000+100); // +100 ms to avoid rounding issues under Firefox
          }
        }
     
        function dispatchPageVisibilityChangeEvent() {
          unifiedVisilityChangeEventDispatchAllowed=false;
          var evt = document.createEvent("Event");
          evt.initEvent("potentialvisilitychange", true, true);
          document.dispatchEvent(evt);
        }
     
        function checkPageVisibility() {
          var potentialHiddenDuration=(hasFocusLocal || lastActionDate==null?0:Math.floor((new Date().getTime()-lastActionDate.getTime())/1000));
                                        document.potentiallyHiddenSince=potentialHiddenDuration;
          if (potentialHiddenDuration>=potentialPageVisibility.pageVisibilityChangeThreshold && !document.potentialHidden) {
            // page visibility change threshold raiched => raise the even
            document.potentialHidden=true;
            dispatchPageVisibilityChangeEvent();
          }
        }
                            
        var lastActionDate=null;
        var hasFocusLocal=true;
        var hasMouseOver=true;
        document.potentialHidden=false;
        document.potentiallyHiddenSince=0;
        var timeoutHandler = null;
     
        addEvent(document, "pageshow", function(event) {
          document.getElementById("x").innerHTML+="pageshow/doc:<br>";
        });
        addEvent(document, "pagehide", function(event) {
          document.getElementById("x").innerHTML+="pagehide/doc:<br>";
        });
        addEvent(window, "pageshow", function(event) {
          document.getElementById("x").innerHTML+="pageshow/win:<br>"; // raised when the page first shows
        });
        addEvent(window, "pagehide", function(event) {
          document.getElementById("x").innerHTML+="pagehide/win:<br>"; // not raised
        });
        addEvent(document, "mousemove", function(event) {
          lastActionDate=new Date();
        });
        addEvent(document, "mouseover", function(event) {
          hasMouseOver=true;
          setAsNotHidden();
        });
        addEvent(document, "mouseout", function(event) {
          hasMouseOver=false;
          initPotentiallyHiddenDetection();
        });
        addEvent(window, "blur", function(event) {
          hasFocusLocal=false;
          initPotentiallyHiddenDetection();
        });
        addEvent(window, "focus", function(event) {
          hasFocusLocal=true;
          setAsNotHidden();
        });
        setAsNotHidden();
      }
    }
     
    potentialPageVisibility.pageVisibilityChangeThreshold=4; // 4 seconds for testing
    potentialPageVisibility.init();
    </script>

由于目前没有有效的跨浏览器解决方案没有误报,因此最好在网站上禁用定期活动时三思而后行。

模板简介:该模板名称为【JavaScript 有没有办法检测浏览器窗口当前是否处于活动状态?】,大小是暂无信息,文档格式为.编程语言,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【JavaScript】栏目查找您需要的精美模板。

相关搜索
  • 下载密码 lanrenmb
  • 下载次数 341次
  • 使用软件 Sublime/Dreamweaver/HBuilder
  • 文件格式 编程语言
  • 文件大小 暂无信息
  • 上传时间 04-18
  • 作者 网友投稿
  • 肖像权 人物画像及字体仅供参考
栏目分类 更多 >
热门推荐 更多 >
html5 微信公众平台 微信文章 微信图片 响应式 企业网站 自适应 微信模板 单页式简历模板 微信素材
您可能会喜欢的其他模板