9

The title explains itself. How can I detect if a web page has gone to background?

I'm implementing a chat application and I'll use this information to decide showing new message notifications. I suppose that GMail uses something like that. If the page is on background, it shows desktop notifications (on chrome), if not it doesn't show them.

natedavisolds
  • 4,305
  • 1
  • 20
  • 25
Cagatay Gurturk
  • 7,186
  • 3
  • 34
  • 44
  • You mean : *If a CHAT popup is opened* ? – Roko C. Buljan Nov 22 '11 at 23:06
  • Think that you're using gmail, reading emails etc. And you received a message, in that case gmail does not show any desktop notification (because the page is on foreground) But if you're navigating on other sites while gmail is still opened, you're warned by a desktop notification. How gmail understands its status? – Cagatay Gurturk Nov 22 '11 at 23:08

3 Answers3

12

I know that the answer has already been selected but I wanted to share another way.

You can use the hasFocus method on the document to see if it has the focus. There is no reason to set your own variable.

Here's some proof of concept code. jsFiddle is at the bottom. Every 3 seconds it will check if the window has focus or not–displaying true or false.

HTML:

<p>This will show if the document has focus every three seconds</p>
<button id="go">Go</button>
<button id="stop">Stop</button>

<ul id="active_log">
</ul>

CSS:

#stop { display: none; }

Javascript inside on document ready:

var timeout = null;

var checkActive = function() {
    var isActive = window.document.hasFocus(),
        $activity = $("<li />").text(isActive.toString());

    $('#active_log').prepend($activity).find('li:nth-child(n+6)').fadeOut(function() {
        $(this).remove();
    });

    timeout = setTimeout(checkActive, 3000);
}

$('#go').click(function() {
    $(this).hide().siblings('button').show();
    checkActive();
});

$('#stop').click(function() {
    $(this).hide().siblings('button').show();
    clearTimeout(timeout);
    timeout = null;
});

http://jsfiddle.net/natedavisolds/2D7za/1/

natedavisolds
  • 4,305
  • 1
  • 20
  • 25
  • I'll use window.document.hasFocus() to decide to show notification. Thanks for inspiring! – Cagatay Gurturk Nov 22 '11 at 23:49
  • Excellent tip! One caveat to keep in mind is this only checks to see if the *document* has focus--seems obvious, but this returns `false` if another frame on the page has focus (testable in the jsFiddle) or if the address bar has focus. – Michelle Tilley Nov 23 '11 at 00:48
  • This will definitely be the more useful cross-browser approach at least for the moment...it might be worth noting that this approach can return false negatives (if the page uses multiple frames, or the user puts the focus outside the document or off of the browser entirely, without hiding the page), but Google's experimental API does the opposite, giving false positives for foreground tabs that are hidden entirely by other windows. So the best approach to use might also depend on whether false positives or negatives are of more concern. – Theodore Murdock Nov 23 '11 at 03:15
7

There's now a page visibility API for this, and it is well-supported by all the most recent versions of major browsers on Windows, Mac OS X, and Linux (though I have not actually tested all browsers with a fair share of the Linux browser market).

The page visibility API is now the best approach for checking visibility; the only caveats are that it can't tell you what parts of the browser window are visible (just that nothing is visible or at least some part is), and that support has only been present since 2016 on Linux, 2015 on Mac, and 2014 (possibly earlier) on Windows.

While support was being rolled out, a false negative was rare, but false positives occurred on some platforms; for example, in 2014, OSX rendered miniature versions of minimized applications in the dock, and as a result of the way this had been done, an application could not easily tell whether it was minimized, as it was still asked to paint the screen. Linux had complications with knowing whether your application was on a non-visible workspace, and whether another window was occluding it.

The first public draft was published in June, 2011, and it reached "recommendation" status in May 2013. By March, 2014, the most recent versions of all major Windows browsers had full support for the standard. Full support for all major Mac browsers was achieved in April, 2015. Linux support was achieved for at least Chromium by August of 2016 (when Chromium issue 293128 was closed); while I have not tested them, I expect other Linux browsers have likely kept pace, as the hardest part of the work seems to have been adjusting OS/GUI tookit contracts and APIs to make knowing whether your desktop application is visible possible.

Theodore Murdock
  • 1,538
  • 1
  • 13
  • 28
  • Very interesting, especially being able to detect the "prerender" state, which has bitten me before... – Michelle Tilley Nov 22 '11 at 23:19
  • I didn't know such a API, thanks. But it seems that it's not so logical to use in production such a experimental API. – Cagatay Gurturk Nov 22 '11 at 23:19
  • 1
    Just to save everybody a couple of clicks: http://caniuse.com/#feat=pagevisibility – Matt Lyons-Wood Sep 01 '15 at 12:27
  • @MattLyons Hmm...that link doesn't seem completely accurate to me. There's nothing in the "about" page that mentions what OS is used for testing, and the OS factor is not insignificant, at least for the page visibility API. It's partly been OS support for allowing applications to recognize whether they are visible or not that has limited browsers in implementing this feature. Only Windows was designed in a way that supported this feature from day one, OSX was showing live thumbnails of minimized applications back then, so they weren't technically not visible. – Theodore Murdock Sep 01 '15 at 20:02
  • Specifically, there are still some issues on Linux that aren't noted there, and I believe Chrome support for the page visibility API was complete earlier than Chrome 42 on Windows. Though I suppose the chart does meet the "if it's green, it mostly works" standard that they claim. – Theodore Murdock Sep 01 '15 at 20:11
4

You can bind to window's blur and focus events. Here is a snippet code from an app I wrote:

$(window).bind("blur", function() {
  Chatterbox.set_focused(false);
});

$(window).bind("focus", function() {
  Chatterbox.set_focused(true);
});
Michelle Tilley
  • 157,729
  • 40
  • 374
  • 311