Reputation: 977
Is there a good angular way to detect window focus? I am using html5 notifications and I would like to only fire if the window is out of focus.
Thanks!
Upvotes: 8
Views: 16432
Reputation: 195
In Cristi Berceanu's answer, he suggests assigning a function to $window.onfocus, which does work. However, there is a problem with that... only one function can be assigned to $window.focus at a time. Thus, by assigning a function to $window.onfocus, you could accidentally overwrite a previous function, and your function will be vulnerable to being overwritten later, too.
Here's a different solution that allows multiple functions to run with the window's focus or blur events:
var onFocus = function () {
// do something
};
var onBlur = function () {
// do something else
};
var win = angular.element($window);
win.on("focus", onFocus);
win.on("blur", onBlur);
This will allow you to assign multiple functions to the focus and blur events for the $window object.
If you added the functions inside a controller and want to remove those functions when the controller is destroyed, you can do something like this:
$scope.$on("$destroy", function handler() {
win.off("focus", onFocus);
win.off("blur", onBlur);
$interval.cancel(interval);
});
Solution inspired by this post: https://www.bennadel.com/blog/2934-handling-window-blur-and-focus-events-in-angularjs.htm
Upvotes: 4
Reputation: 1693
There's a built-in angular directive ngFocus
here maybe it helps if you attach it to the body
<window, input, select, textarea, a
ng-focus="">
...
</window, input, select, textarea, a>
Edit: For window focus, there's the $window
wrapper and you can do something like:
$window.onfocus = function(){
console.log("focused");
}
Upvotes: 5
Reputation: 12343
Edit @CristiBerceanu is right - you should use the built-in ng-focus directive. However, take this answer as a guideline for any missing event you want to bind.
You must create a directive:
angular
.module('MyModule', [])
.directive('onFocus', function(){
return {
restrict: 'A',
scope: {
'focus': '&onFocus'
},
link: function($scope, $element, $attributes) {
var focus = function(event) {
$scope.focus({'$event': event});
};
$element.on("focus", focus);
$scope.$on('$destroy', function(){
$element.off('focus', onClick);
});
}
}
});
Notice how the event is bound in the directive by jquery and NOT directly in the controller. Additionally, notice that a bound expression is tied using the &
prefix (evaluable expression binding) instead of regular prefixes like @
(text-binding) or =
(scope property reference, bi-directional, binding).
Upvotes: 5
Reputation: 5435
you can write a directive to attach to the body element and inside it you can use $window.onfocus event to notify your angular app using events or a service, the same thing you can do from inside a service, it all depends on your architecture
Upvotes: 1