Como detectar quando uma guia está focada ou não no Chrome com Javascript?

Preciso saber se o usuário está visualizando uma guia ou não no Google Chrome. Eu tentei usar o desfoque de events e foco vinculado à janela, mas apenas o borrão parece estar funcionando corretamente.

window.addEventListener('focus', function() { document.title = 'focused'; }); window.addEventListener('blur', function() { document.title = 'not focused'; }); 

O evento de foco funciona de maneira estranha, apenas às vezes. Se eu alternar para outra guia e voltar, o evento de foco não será ativado. Mas se eu clicar na barra de endereços e depois voltar na página, isso acontecerá. Ou, se eu mudar para outro programa e voltar ao Chrome, ele será ativado se a guia estiver focalizada no momento.

Atualização de 2015: A nova maneira de HTML5 com a API de visibilidade (tirada do comentário de Blowsie):

 document.addEventListener('visibilitychange', function(){ document.title = document.hidden; // change tab text for demo }) 

O código que o pôster original dá (na pergunta) agora funciona a partir de 2011:

 window.addEventListener('focus', function() { document.title = 'focused'; }); window.addEventListener('blur', function() { document.title = 'not focused'; }); 

edit : A partir de alguns meses depois no Chrome 14, isso ainda funcionará, mas o usuário deve ter interagido com a página clicando em qualquer lugar da janela pelo menos uma vez. Simplesmente rolagem e tal é insuficiente para fazer este trabalho. Fazer window.focus() também não faz isso funcionar automaticamente. Se alguém souber de uma solução alternativa, por favor mencione.

A resposta selecionada para a pergunta Existe uma maneira de detectar se uma janela do navegador não está ativa no momento? Deveria trabalhar. Ele utiliza a API Visibilidade da Página elaborada pelo W3C em 2011-06-02.

Pode funcionar, afinal, fiquei curioso e escrevi este código:

 ... setInterval ( updateSize, 500 ); function updateSize(){ if(window.outerHeight == window.innerHeight){ document.title = 'not focused'; } else { document.title = 'focused'; } document.getElementById("arthur").innerHTML = window.outerHeight + " - " + window.innerHeight; } ... 
dent

Este código faz exatamente o que você quer, mas de uma maneira feia. O problema é que o Chrome parece ignorar a mudança de título de tempos em tempos (quando se muda para a guia e mantém o mouse pressionado por 1 segundo, parece sempre criar esse efeito).

Você terá valores diferentes em sua canvas, mas seu título não será alterado.

Conclusão: O que quer que você esteja fazendo, não confie no resultado ao testá-lo!

Para quem quiser trocar títulos de página por desfoque e voltar ao título da página original em foco:

 // Swapping page titles on blur var originalPageTitle = document.title; window.addEventListener('blur', function(){ document.title = 'Don\'t forget to read this...'; }); window.addEventListener('focus', function(){ document.title = originalPageTitle; }); 

Eu achei que adicionar onblur = e onfocus = events inline contornou o problema:

Isso poderia funcionar com o JQuery

 $(function() { $(window).focus(function() { console.log('Focus'); }); $(window).blur(function() { console.log('Blur'); }); }); 

No chrome, você pode executar um script de segundo plano com um tempo limite menor que 1 segundo e, quando a guia não tiver foco, o chrome só o executará a cada segundo. Exemplo;

Isso não funciona no Firefox ou no Opera. Não sei sobre outros navegadores, mas duvido que funcione lá também.

 var currentDate = new Date(); var a = currentDate.getTime(); function test() { var currentDate = new Date(); var b = currentDate.getTime(); var c = b - a; if (c > 900) { //Tab does not have focus. } else { //It does } a = b; setTimeout("test()",800); } setTimeout("test()",1);