Como saber se o aplicativo / página está em foco

Na verdade, há uma API de visibilidade de página, documentada no MDN .

No entanto, ele só funciona quando o usuário alterna as guias dentro da janela do navegador. Se a janela do navegador em si perder o foco (enquanto sua guia estiver selecionada), a API de visibilidade da página não dirá que você perdeu o foco! Isso pode ser visto nesta página de demonstração para a API de visibilidade . Veja o que acontece quando alterna entre as guias e quando você alterna para outra janela.

Por outro lado, temos uma função genérica, document.hasFocusque pode nos dizer se a guia está focada ou não, neste momento.

Também temos eventos de “desfoque” e “foco” anexados ao windowobjeto, que são disparados quando o navegador entra ou sai de foco.

A API de visibilidade expõe outro evento, “visibilitychange”, que é disparado quando a guia atual sai de foco (dentro do contexto da janela do navegador).

Precisamos combinar esses dois mecanismos. Usarei o knockout porque nos dá observáveis ​​que podemos “assinar” quando eles mudam; que usaremos para detectar eventos de foco.

var page_has_focus = ko.observable();

var checkFocus = function() {
page_has_focus
(document.hasFocus());
}

Em seguida, nos inscrevemos em todos os eventos que mudam o foco:

document.addEventListener("visibilitychange", checkFocus);
window
.addEventListener("focus", checkFocus);
window
.addEventListener("blur", checkFocus);

Mas espere, há um problema. Nem todos os navegadores expõem o evento de alteração de visibilidade como “alteração de visibilidade”. Consulte novamente os documentos MDN para isso.

Então, nós o tornamos cross-browser:

var visibilityChange;
if (typeof document.hidden !== "undefined") {
visibilityChange
= "visibilitychange";
} else if (typeof document.mozHidden !== "undefined") {
visibilityChange
= "mozvisibilitychange";
} else if (typeof document.msHidden !== "undefined") {
visibilityChange
= "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
visibilityChange
= "webkitvisibilitychange";
}

document
.addEventListener(visibilityChange, checkFocus);
window
.addEventListener("focus", checkFocus);
window
.addEventListener("blur", checkFocus);

E para tornar o código mais limpo, envolvemos tudo em um IIFE (função imediatamente invocada) e para torná-lo extra robusto, retornaremos uma versão somente leitura do observável, envolvendo-o em um cálculo simples.

Então, aqui está o resultado:

var page_has_focus = (function() {
var page_has_focus = ko.observable();

var checkFocus = function() {
page_has_focus
(document.hasFocus());
}
checkFocus
(); // init

var visibilityChange;
if (typeof document.hidden !== "undefined") {
visibilityChange
= "visibilitychange";
} else if (typeof document.mozHidden !== "undefined") {
visibilityChange
= "mozvisibilitychange";
} else if (typeof document.msHidden !== "undefined") {
visibilityChange
= "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
visibilityChange
= "webkitvisibilitychange";
}

document
.addEventListener(visibilityChange, checkFocus);
window
.addEventListener("focus", checkFocus);
window
.addEventListener("blur", checkFocus);

return ko.computed(function() {
return page_has_focus();
});
})();

Agora vamos testar!

Digite o seguinte no console:

page_has_focus.subscribe(function(yes) {
if(yes) {
console
.log("Page got focus");
} else {
console
.log("Page lost focus");
}
});

Agora, se você alternar as guias e voltar, verá “A página perdeu o foco” seguido por uma mensagem “A página obteve o foco” no console.

Se você mudar para outro aplicativo e voltar, verá o mesmo.

Você também pode tentar alternar para outro aplicativo de forma que o console ainda esteja visível; e você ainda verá o mesmo resultado.

Observação: o próprio console conta como outra guia; então, depois de digitar o código no console, clique dentro do documento para focalizá-lo.