Using the page visibility API in an AngularJS project

The page visibility api allows developers and designers to
control when the user is actually on the page, and when the user is away, for example the tab is
opened but not in focus, or the browser is minimized.

The first use I did of this api is to interrupt server side refreshes of the data, while the user is
not on the page, to avoid consumption of server side resources.

The specification gives us two tools: the first one is a variable document.hidden which is
true if the page is not on focus, and false while the user is actually on the page. The second tool we have is
an event: visibilitychange which tells us when to look for the value of that variable.

So far so good, but how can we use this?

The normal implementation would be:


document.addEventListener("visibilitychange", function() { if (document.hidden) { // The document is not on focus // so, let's handle this } else { // The document is on focus // do our things. } }, false);

The project I am working on uses AngularJS, I could use this snippet in the controller, but
is not the most elegant way to handle this. What we are going to do then is a service, which
will broadcast an event when the page visibility changes, which can be detected somewhere else
in our controllers.


myAPp .service('visibilityApiService', function visibilityApiService($rootScope) { document.addEventListener("visibilitychange",visibilitychanged); document.addEventListener("webkitvisibilitychange", visibilitychanged); document.addEventListener("msvisibilitychange", visibilitychanged); function visibilitychanged() { $rootScope.$broadcast('visibilityChanged', document.hidden || document.webkitHidden || document.mozHidden || document.msHidden) } })

At the moment of writing the visibility API
is supported without the vendor prefix in Firefox, but requires a prefix for Chrome
and Internet Explorer (10+).

Somewhere else in the application, for example in a controller, we can listen for the
visibilityChanged event, broadcasted by our service:


$scope.$on('visibilityChanged', function(event, isHidden) { if (document.hidden) { // The document is not on focus // so, let's handle this } else { // The document is on focus // do our things. } });