Ali Briceño
Ali Briceño

Reputation: 1134

Angular 2+ window.onfocus and windows.onblur

So I need in Angular 2 or 4 to manage when the browser tab of my app is focused or not. Is there any way to use the window.onfocus and window.onblur ?

Thanks a lot

Upvotes: 23

Views: 15029

Answers (3)

schmkr
schmkr

Reputation: 133

In a more reactive approach, I use this injection token:

export const WINDOW_FOCUS = new InjectionToken<Observable<boolean>>(
    'Shared Observable based on `window focus/blurred events`',
    {
        factory: () => {    
            return merge(fromEvent(window, 'focus'), fromEvent(window, 'blur')).pipe(
                startWith(null),
                map(() => window.document.hasFocus()),
                distinctUntilChanged(),
                share(),
            );
        },
    },
);

Ideally, you do not want to rely on the global windows variable, you could replace it with injecting the WINDOW and DOCUMENT tokens from https://github.com/ng-web-apis/common.

To use the WINDOW_FOCUS injection token, in any component or service, it can be added to the constructor like this:

@Injectable()
export class SomeService {
    constructor(
        @Inject(WINDOW_FOCUS) private readonly windowFocus$: Observable<boolean>
    ) {} 
}

Upvotes: 1

Andr&#233; C. Andersen
Andr&#233; C. Andersen

Reputation: 9375

Turns out this doesn't work in services, which was my requirement. My solution was doing it "the old way":

@Injectable()
export class WindowService {
    constructor(){
        window.addEventListener('focus', event => {
            console.log(event);
        });
        window.addEventListener('blur', event => {
            console.log(event);
        });
    }
}

Not sure I did it the "correct" way, but it works on Chrome. What I'm not sure about is if I should destroy the event listener or not, and if it works in other browsers. Let me know if I'm inadvertently shooting myself in the foot here. Will update answer if so, or delete it if need be.

Upvotes: 6

dlcardozo
dlcardozo

Reputation: 4013

You can use a component with @HostListener.

Something like:

@Component({})
export class WindowComponent {

constructor(){}

    @HostListener('window:focus', ['$event'])
    onFocus(event: any): void {
        // Do something
    }

    @HostListener('window:blur', ['$event'])
    onBlur(event: any): void {
        // Do something
    }

}

Just check that you don't have multiple WindowComponent running at the same time, because you will have an unexpected behavior, due that each instance will react to these events.

Upvotes: 44

Related Questions