简体   繁体   中英

Detect If Browser Tab Has Focus

Is there a reliable cross-browser way to detect that a tab has focus.

The scenario is that we have an application that polls regularly for stock prices, and if the page doesn't have focus we could stop the polling and save everyone the traffic noise, especially as people are fans of opening several tabs with different portfolios.

Is window.onblur and window.onfocus an option for this?

Yes, window.onfocus and window.onblur should work for your scenario:

http://www.thefutureoftheweb.com/blog/detect-browser-window-focus

Surprising to see nobody mentioned document.hasFocus

if (document.hasFocus()) console.log('Tab is active')

MDN has more information.

Important Edit:<\/em><\/strong> This answer is outdated. Since writing it, the Visibility API ( mdn<\/a> , example<\/a> , spec<\/a> ) has been introduced. It is the better way to solve this problem.


var focused = true;

window.onfocus = function() {
    focused = true;
};
window.onblur = function() {
    focused = false;
};

While searching about this problem, I found a recommendation that Page Visibility API<\/a> should be used. Most modern browsers support this API according to Can I Use: http:\/\/caniuse.com\/#feat=pagevisibility<\/a> .

$(document).ready(function() {
  var hidden, visibilityState, visibilityChange;

  if (typeof document.hidden !== "undefined") {
    hidden = "hidden", visibilityChange = "visibilitychange", visibilityState = "visibilityState";
  } else if (typeof document.msHidden !== "undefined") {
    hidden = "msHidden", visibilityChange = "msvisibilitychange", visibilityState = "msVisibilityState";
  }

  var document_hidden = document[hidden];

  document.addEventListener(visibilityChange, function() {
    if(document_hidden != document[hidden]) {
      if(document[hidden]) {
        // Document hidden
      } else {
        // Document shown
      }

      document_hidden = document[hidden];
    }
  });
});

Yes those should work for you. You just reminded me of this link I came across that exploits those techniques. interesting read

I would do it this way (Reference http://www.w3.org/TR/page-visibility/ ):

    window.onload = function() {

        // check the visiblility of the page
        var hidden, visibilityState, visibilityChange;

        if (typeof document.hidden !== "undefined") {
            hidden = "hidden", visibilityChange = "visibilitychange", visibilityState = "visibilityState";
        }
        else if (typeof document.mozHidden !== "undefined") {
            hidden = "mozHidden", visibilityChange = "mozvisibilitychange", visibilityState = "mozVisibilityState";
        }
        else if (typeof document.msHidden !== "undefined") {
            hidden = "msHidden", visibilityChange = "msvisibilitychange", visibilityState = "msVisibilityState";
        }
        else if (typeof document.webkitHidden !== "undefined") {
            hidden = "webkitHidden", visibilityChange = "webkitvisibilitychange", visibilityState = "webkitVisibilityState";
        }


        if (typeof document.addEventListener === "undefined" || typeof hidden === "undefined") {
            // not supported
        }
        else {
            document.addEventListener(visibilityChange, function() {
                console.log("hidden: " + document[hidden]);
                console.log(document[visibilityState]);

                switch (document[visibilityState]) {
                case "visible":
                    // visible
                    break;
                case "hidden":
                    // hidden
                    break;
                }
            }, false);
        }

        if (document[visibilityState] === "visible") {
            // visible
        }

    };  

Posting this answer because I found a bug in accepted answer.

The bug is when you open a developer console on the focused window and click anywhere on it, the developer console has the focus now, at this point window.onfocus or window.onblur has no effect whatsoever.

So here is my solution,

document.addEventListener("visibilitychange", function() {
    if (document.visibilityState === 'visible') {
        console.log('has focus');
    } else {
        console.log('lost focus');
    }
});

Read more https://developer.mozilla.org/en-US/docs/Web/API/Document/visibilitychange_event

Cross Browser jQuery Solution!<\/strong> Raw available at GitHub<\/a><\/sub>

<\/blockquote>

<\/h2>

The following plugin will go through your standard test for various versions of IE, Chrome, Firefox, Safari, etc.. and establish your declared methods accordingly. It also deals with issues such as:

  • <\/li>
  • <\/li>
    • <\/li><\/ul><\/li>
    • <\/li><\/ul>

      Use is as simple as: Scroll Down to ' Run Snippet<\/em> '<\/sub>

This is 10 years old. Here is a newer version: Pause/resume CSS animations when switching tabs

Basicly use Mozillas Javascript https://developer.mozilla.org/en-US/docs/Web/API/Window/focus_event

 function pause() {

 //Do something

 }

 function play() {

 //Do something

 }
 window.addEventListener('blur', pause);
 window.addEventListener('focus', play);

A React hook version based on all these fine gentlemen's answers here above:

import { useEffect, useState } from 'react';

const EVENT_NAME = 'visibilitychange';

export const useTabFocus = () => {
    const [hasFocus, setHasFocus] = useState(isVisible());

    useEffect(() => {
        const onVisibilityChange = () => {
            setHasFocus(isVisible());
        };

        document.addEventListener(EVENT_NAME, onVisibilityChange);

        return () => {
            document.removeEventListener(EVENT_NAME, onVisibilityChange);
        };
    }, []);

    return hasFocus;
};

const isVisible = () => document.visibilityState === 'visible';

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM