【问题标题】:Detect if browser tab is active or user has switched away检测浏览器选项卡是否处于活动状态或用户已切换
【发布时间】:2013-10-31 10:07:16
【问题描述】:

如何检测用户是否正在切换到另一个浏览器选项卡?

目前,我有这个:

$(window).on("blur focus", function (e) {

    var prevType = $(this).data("prevType");

    if (prevType != e.type) { //  reduce double fire issues
        switch (e.type) {
            case "blur":
                $('.message').html('<div class="alert alert-error">Oops. You navigated away from the ads <a id="start" class="butt green">Resume</a></div>');

                var myDiv = $("#bar");
                myDiv.clearQueue();
                myDiv.stop();
                clearInterval($timer);
                $timer = null;
                break;
            case "focus":
                // do work
                break;
        }
    }

    $(this).data("prevType", e.type);
});

但这仅在用户最小化活动窗口时才有效。

【问题讨论】:

  • 在我看来,那些问答已经过时了。可见性 API 现在可以提供更好的答案。
  • 我同意dystroy。他们都是四岁以上;从那时起,网络发生了很大变化。但是,oliverbj,您最好将这些作为使用旧浏览器的人的参考。
  • @MattGrande 也许更新后的答案也应该在那里发布,那么?
  • @JanDvorak 我在两个问题上都写了两个 cmets。

标签: javascript jquery


【解决方案1】:

这是一个 ES6 多浏览器解决方案,我用它来确定选项卡的可见性。我从 Deny 的解决方案中汲取灵感,并根据我的需要对其进行了定制。

const vis = (c) => {
  let self = this
  const browserProps = {
    hidden: "visibilitychange",
    msHidden: "msvisibilitychange",
    webkitHidden: "webkitvisibilitychange",
    mozHidden: "mozvisibilitychange",
  }
  for (item in browserProps) {
    if (item in document) {
      eventKey = browserProps[item]
      break
    }
  }

  if (c) {
    if (!self._init && !(typeof document.addEventListener === "undefined")) {
      document.addEventListener(eventKey, c)
      self._init = true
      c()
    } 
  }
  return  !document[item] 
}

vis(() => {
  let tabVisibility = vis() ? 'Visible' : 'Not visible';
  console.log(tabVisibility)
})

【讨论】:

    【解决方案2】:

    如果您想检测标签是否对用户可见,请使用document.visibilityState 执行检查(只读属性)。尽管document.hidden 也可以工作,正如其他人所写的那样,然后W3C considers it 'historical' 并建议使用前一种方法。

    如果您只想知道标签是否活动,请使用document.hasFocus() 执行检查。在这种情况下,该选项卡可能仍然可见,但不处于活动状态(例如,两个并行视图浏览器窗口,其中只有一个处于活动状态,两个都可见)。

    如果您想捕获可见状态的更改(当然在这种情况下也是活动状态),然后从Page Visibility API 监听visibilitychange 事件。

    使用所有三个的示例

    // Capture change to visibility
    document.addEventListener("visibilitychange", function() {
        // Check if tab content is visible
        if (document.visibilityState) { 
            console.log("Tab is visible!") 
        }
    
        // Check if tab is active
        if (document.hasFocus()) {
            console.log("Tab is active!");
        }
    });
    

    处理浏览器兼容性

    您可以设置以下检查以覆盖不兼容的浏览器。

    注意:不包括hasFocus(),因为它是compatible all the way to IE6

    var visibilityState, visibilityChange;
    if (typeof document.visibilityState !== "undefined") {
        visibilityState = "visibilityState";
        visibilityChange = "visibilitychange";
    } 
    else if (typeof document.mozVisibilityState !== "undefined") {
        visibilityState = "mozVisibilityState";
        visibilityChange = "mozvisibilitychange";
    } 
    else if (typeof document.msVisibilityState !== "undefined") {
        visibilityState = "msVisibilityState";
        visibilityChange = "msvisibilitychange";
    } 
    else if (typeof document.webkitVisibilityState !== "undefined") {
        visibilityState = "webkitVisibilityState";
        visibilityChange = "webkitvisibilitychange";
    }
    
    if (visibilityChange != null && visibilityState != null) {
        document.addEventListener(visibilityChange, function() {
            if (document[visibilityState]) { 
                console.log("Tab is visible!") 
            }
        }, false);
    }
    

    快速 MDN 参考

    【讨论】:

      【解决方案3】:

      案例 1

      只需将EventListener 添加到您的构造函数

      document.addEventListener("visibilitychange", function() {
            if (document.hidden) {
              //do whatever you want
              console.log("Hidden");
            }
            else {
              //do whatever you want
              console.log("SHOWN");
            }
      });

      案例 2

      请参见此处如果您更改标签$(window).blur(function () 函数将调用,如果您再次来到此标签$(window).focus(function () 函数将调用。 在您的构造函数中添加此代码

      $(window).focus(function () {
            //do something
             console.log("You are in this tab");
      });
      
      $(window).blur(function () {
            //do something
             console.log("You left this tab");
      })
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <p>Click here and click outside of this..</p>

      【讨论】:

        【解决方案4】:

        这 3 行代码对我有用

        document.addEventListener("visibilitychange", function() {
              document.title = document.hidden ? "I'm away" : "I'm here";
        });
              
        

        参考链接:document.hidden

        演示:https://iamsahilralkar.github.io/document-hidden-demo/

        【讨论】:

        【解决方案5】:

        现在我们可以使用visibility API

        为了处理不同的浏览器特定语法,我做了这个小代码:

        var vis = (function(){
            var stateKey, eventKey, keys = {
                hidden: "visibilitychange",
                webkitHidden: "webkitvisibilitychange",
                mozHidden: "mozvisibilitychange",
                msHidden: "msvisibilitychange"
            };
            for (stateKey in keys) {
                if (stateKey in document) {
                    eventKey = keys[stateKey];
                    break;
                }
            }
            return function(c) {
                if (c) document.addEventListener(eventKey, c);
                return !document[stateKey];
            }
        })();
        

        用法:

        var visible = vis(); // gives current state
        
        vis(aFunction);      // registers a handler for visibility changes
        

        例子:

        vis(function(){
          document.title = vis() ? 'Visible' : 'Not visible';
        });
        

        Demonstration page

        【讨论】:

        • 谢谢,但我无法在 angularjs 中输出您的代码。它不工作
        • @Ali.NET 我在所有浏览器上都使用它
        • 在 Firefox 41 (Linux) 中无法正常工作。如果我切换浏览器选项卡,它可以正常工作。如果我最小化浏览器窗口,它也可以工作。但是如果我切换到另一个应用程序,它就不起作用。即使另一个窗口处于活动状态,document.hidden 属性仍保持为 false
        • @pumbo 是的,可见性 API 目前并不总是能够知道其他应用程序是否隐藏了浏览器。我认为目前没有办法获取这些信息。
        • @waterkinq 没有可靠的方法来关闭标签/浏览器。这是一种设计选择(5 年前的情况不同)。这意味着您必须绝不依赖浏览器通知您断开连接,您必须在服务器端正确处理它。
        猜你喜欢
        • 2011-10-22
        • 2020-11-23
        • 1970-01-01
        • 2010-12-18
        • 1970-01-01
        • 2017-10-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多