5

On my site I have an important notification that prompts a native alert() in order to bring the site to the foreground if the window is not already focused. The problem is that on some browsers, if the user is in another desktop application (Photoshop, Microsoft Word, etc), it will not bring the browser on top of that application. In this case the alert is pretty much useless and I would like to omit it (since it blocks the other scripts on my page).

Is there a way to tell that a browser is the active application on a device? Or is there a different, non-blocking way to bring a window to the foreground?

Thanks!

Clarifications: I already know how to check if a window is active within a browser, but I just don't know how to check if the browser application itself is active. Also, browsers I need to support are Chrome, Safari, Firefox, and IE >= 9

Tatermelon
  • 489
  • 2
  • 10

3 Answers3

2

You should use the new Notification object. It works even when the browser is not focused, and is useful for sending the user important notifications.

Example: http://jsfiddle.net/howderek/792km8td/

document.getElementById('notif').onclick = function () {
    
    function notify () {
        var notification = new Notification('Test!');
    }
    
    
    if (Notification.permission === "granted") {
        setTimeout(notify, 5000);        
    } else {
        Notification.requestPermission(function () {
            if (Notification.permission === "granted") {
                setTimeout(notify, 5000);        
            }             
        });
    }
}

https://developer.mozilla.org/en-US/docs/Web/API/notification

Community
  • 1
  • 1
howderek
  • 2,224
  • 14
  • 23
  • Is that cross-browser compatible? – Tatermelon Apr 16 '15 at 19:05
  • [Not IE :(](http://caniuse.com/#feat=notifications) but you could have an alert fallback and just use @AI.G's solution as a fallback for browsers that don't support Notification – howderek Apr 16 '15 at 19:06
  • is there a way to set the duration of the notification? In your jsfiddle it seems that it only shows for a few seconds then disappears. – Tatermelon Apr 16 '15 at 19:12
  • It doesn't appear there is a way to increase the duration of the notification. – howderek Apr 16 '15 at 19:33
2

You can use the Page Visibility API for this.

It is compatible with IE 10+.

Small example of code:

document.addEventListener("visibilitychange", function(e) {
  console.log("visibility changed!", e);
  if (document.visibilityState === 'visible') {
    console.info("window is visible now!");
  }
  else {
    console.info("something else, maybe you changed tab or minimized window!");
  }
  console.log("check the visibilityState property on document object for more info");
});

This will work even if the user minimizes the browser while the tab is open, so I guess this suits your needs :)

user3459110
  • 6,961
  • 3
  • 26
  • 34
  • That's very useful, but it still doesn't satisfy my requirement =/. I still cannot tell the difference between the window being in a hidden tab and the window being covered by another, non-browser application. – Tatermelon Apr 16 '15 at 20:02
  • @Tatermelon You mean at the time when your application, after doing something, arrives to a point when it is ready to fire an alert/notification? You can check the `visibilityState` property _before_ the notification fires :) I demonstrated it within an event function, but it is not limited to events. The static getter will always be there. – user3459110 Apr 16 '15 at 20:07
  • I know I can always check it, but my problem is that I only want to fire an alert if the browser (any window) is active AND my specific browser window is hidden. With visibilityState I can check if the window is hidden, but I can't tell whether it is being hidden by another browser window or by another application. – Tatermelon Apr 16 '15 at 20:11
  • @Tatermelon Ah. Then I mis-understood your problem, my bad. AFAIK, there is no API exposed by browsers to tell whether your tab is hidden by another same browser's instance or not. The sandboxed environment in which JavaScript runs further makes this very difficult to expose. Also, the fact that `alert`s bring the window to focus is not reliable itself in the first place, due to which using the visibility API is your best bet for now :) – user3459110 Apr 16 '15 at 20:19
  • That makes sense. I think what I will do is use the Notification API as @howderek suggested for Chrome/FF/Safari, and for IE I will use alerts when visibilityState is hidden. At least it takes care of the case when part of the window is visible behind another application. I wish I could give both of you credit for the answer! – Tatermelon Apr 16 '15 at 20:37
0

Have a global variable storing whether the window is active or not:

var window_active = true;

Now add event listeners to "listen" for window (de)activation:

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

And when you call the alert function, check that global variable:

if (window_active)
    alert("notification");

I want to mention that if you change the tab or click the url-bar, the window will be deactivated, which might be not what you want.

Al.G.
  • 4,327
  • 6
  • 31
  • 56
  • I think this only tell you if a window/tab within the browser is active. It doesn't tell you if the actual browser application is active. – Tatermelon Apr 16 '15 at 19:00