JavaScript / jQuery: prueba si la ventana tiene el foco

80

¿Cómo se prueba si el navegador tiene el foco?

varilla
fuente
Consulte también stackoverflow.com/questions/483741/… que también puede responder a esta pregunta.
Alexander Bird
15
Pruebe document.hasFocus(), que devuelve un booleano. Está integrado en la especificación, por lo que se puede hacer sin jQuery.
Braden Best
Para alguien que quiera verificar la visibilidad de las páginas (que no es lo mismo que el enfoque), consulte la API de visibilidad de la página para obtener más detalles.
tsh

Respuestas:

79

No lo he probado en otros navegadores, pero parece funcionar en Webkit. Te dejaré probar IE. : o)

Pruébelo: http://jsfiddle.net/ScKbk/

Después de hacer clic para iniciar el intervalo, cambie el enfoque de la ventana del navegador para ver el cambio de resultado. Nuevamente, probado solo en Webkit.

var window_focus;

$(window).focus(function() {
    window_focus = true;
}).blur(function() {
    window_focus = false;
});

$(document).one('click', function() {
    setInterval(function() {
        $('body').append('has focus? ' + window_focus + '<br>');
    }, 1000);
});​
usuario113716
fuente
@jball - ¿Debe ser IE? En Webkit y Firefox, cualquier activación de la ventana activa el foco. Me pregunto si hay una solución para IE. Además, ¿probaste en tu página? ¿Quizás haya un problema porque jsFiddle usa marcos?
user113716
Chrome en realidad. Después de más pruebas, mi primer comentario podría estar equivocado: la tecla de tabulación que se rompe parece ser más consistente.
jball
@jball: supongo que la tecla de tabulación la rompe porque jsFiddle tiene muchos elementos de entrada en otros marcos. Deshágase de los marcos y apuesto a que funcionará un poco mejor para usted.
user113716
Creo que cada cuadro tiene su propio windowobjeto, por lo que si usara cuadros, probablemente solo necesitaría incluir el script en cada uno.
user113716
4
Utilice window.toppara comprobar la ventana superior.
Mårten Wikström
160

utilice el método hasFocus del documento. Puede encontrar una descripción detallada y un ejemplo aquí: método hasFocus

EDITAR: violín agregado http://jsfiddle.net/Msjyv/3/

HTML

Currently <b id="status">without</b> focus...

JS

function check()
{
    if(document.hasFocus() == lastFocusStatus) return;

    lastFocusStatus = !lastFocusStatus;
    statusEl.innerText = lastFocusStatus ? 'with' : 'without';
}

window.statusEl = document.getElementById('status');
window.lastFocusStatus = document.hasFocus();

check();
setInterval(check, 200);
gumape
fuente
3
Probé el ejemplo del enlace anterior y funcionó bien en IE7 +, Chrome y FF4. +1 para ti.
Joseph Lust
1
Gran función, funciona mucho mejor que otros equivalentes de jQuery con los que me he encontrado.
Heath
3
Más útil que la respuesta aceptada, tuve problemas con la carga del temporizador mientras la ventana estaba desenfocada.
Kokos
Opera no lo admite. El hecho tranquilizador es que están en proceso de cambiar el motor de renderizado a Webkit :)
Nikola Petkanski
6
Mientras tanto, puede usar algo como esto para obtener la funcionalidad en Opera: if(typeof document.hasFocus === 'undefined') { document.hasFocus = function () { return document.visibilityState == 'visible'; } }
Kent
3

Fragmento de JavaScript simple

Basado en eventos:

function focuschange(fclass) {
    var elems=['textOut','textFocus'];
    for (var i=0;i<elems.length;i++) {
        document.getElementById(elems[i]).
            setAttribute('class',fclass);
    }
}
window.addEventListener("blur",function(){focuschange('havnt')});
window.addEventListener("focus",function(){focuschange('have')});
focuschange('havnt');
.have                { background:#CFC; }
#textOut.have:after  { content:'';      }
.havnt               { background:#FCC; }
#textOut.havnt:after { content:' not';  }
<span id='textOut'>Have</span><span id='textFocus'> focus</span>

Grupo de intervalos basado:

setInterval(function() {
    var fclass='havnt';
    if (document.hasFocus()) {
      fclass='have';
    };
    var elems=['textOut','textFocus'];
    for (var i=0;i<elems.length;i++) {
        document.getElementById(elems[i]).
            setAttribute('class',fclass);
    }
},100);
#textOut.have:after  { content:'';     }
#textOut.havnt:after { content:' not'; }
.have  { background:#CFC; }
.havnt { background:#FCC; }
<span id='textOut'>Have</span><span id='textFocus'> focus</span>

F. Hauri
fuente
Me gusta esta respuesta debido a la solución basada en eventos . En mi humilde opinión, siempre debería ser la forma preferida.
cuasi
1

HTML:

<button id="clear">clear log</button>
<div id="event"></div>

Javascript:

$(function(){

    $hasFocus = false;

    $('#clear').bind('click', function() { $('#event').empty(); });

    $(window)
        .bind('focus', function(ev){
            $hasFocus = true;
            $('#event').append('<div>'+(new Date()).getTime()+' focus</div>');
        })
        .bind('blur', function(ev){
            $hasFocus = false;
            $('#event').append('<div>'+(new Date()).getTime()+' blur</div>');
        })
        .trigger('focus');

    setInterval(function() {
        $('#event').append('<div>'+(new Date()).getTime()+' has focus '+($hasFocus ? 'yes' : 'no')+'</div>');
    }, 1000);
});​

prueba

ACTUALIZAR:

Lo arreglaré, pero IE no funciona muy bien

actualización de prueba

andres descalzo
fuente
Aparentemente, el desenfoque no se activa cuando se cambia de pestaña. :(
Jethro Larson