JavaScript / jQuery: Testen Sie, ob das Fenster den Fokus hat

80

Wie testen Sie, ob der Browser den Fokus hat?

Stange
quelle
Siehe auch stackoverflow.com/questions/483741/…, das auch diese Frage beantworten kann.
Alexander Bird
15
Try document.hasFocus(), das einen Booleschen Wert zurückgibt. Es ist in die Spezifikation integriert, sodass es ohne jQuery ausgeführt werden kann.
Braden Best
Für jemanden, der die Sichtbarkeit von Seiten überprüfen möchte (was nicht mit dem Fokus identisch ist), überprüfen Sie bitte die API für die Sichtbarkeit von Seiten, um weitere Informationen zu erhalten.
tsh

Antworten:

79

Ich habe dies nicht in anderen Browsern getestet, aber es scheint in Webkit zu funktionieren. Ich lasse Sie IE versuchen. :Ö)

Probieren Sie es aus: http://jsfiddle.net/ScKbk/

Ändern Sie nach dem Klicken zum Starten des Intervalls den Fokus des Browserfensters, um die Ergebnisänderung anzuzeigen. Wieder nur in Webkit getestet.

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);
});​
user113716
quelle
@jball - Muss IE sein? In Webkit und Firefox löst jede Aktivierung des Fensters den Fokus aus. Ich frage mich, ob es eine Problemumgehung für IE gibt. Haben Sie auch auf Ihrer Seite getestet? Vielleicht gibt es ein Problem, weil die jsFiddle Frames verwendet?
user113716
Chrome eigentlich. Nach weiteren Tests könnte mein erster Kommentar falsch sein - die Tabulatortaste scheint konsistenter zu sein.
Jball
@jball - Ich vermute, dass die Tabulatortaste es kaputt macht, weil jsFiddle viele Eingabeelemente in anderen Frames hat. Werde die Frames los und ich wette, es wird ein bisschen besser für dich funktionieren.
user113716
Ich glaube, jeder Frame hat sein eigenes windowObjekt. Wenn Sie also Frames verwenden würden, müssten Sie wahrscheinlich nur das Skript in jeden einfügen.
user113716
4
Verwenden window.topSie diese Option, um das oberste Fenster zu überprüfen.
Mårten Wikström
160

Verwenden Sie die hasFocus-Methode des Dokuments. Eine ausführliche Beschreibung und ein Beispiel finden Sie hier: hasFocus-Methode

BEARBEITEN: Geige hinzugefügt 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);
Kaugummi
quelle
3
Ich habe das Beispiel über den obigen Link ausprobiert und es hat in IE7 +, Chrome und FF4 gut funktioniert. +1 für dich.
Joseph Lust
1
Tolle kleine Funktion, funktioniert viel besser als andere jQuery-Äquivalente, auf die ich gestoßen bin.
Heath
3
Nützlicher als die akzeptierte Antwort: Ich hatte Probleme mit dem Laden des Timers, während das Fenster unscharf war.
Kokos
Dies wird von Opera nicht unterstützt. Die beruhigende Tatsache ist, dass sie gerade dabei sind, die Rendering-Engine auf Webkit
umzustellen
6
In der Zwischenzeit können Sie so etwas verwenden, um die Funktionalität in Opera zu erhalten: if(typeof document.hasFocus === 'undefined') { document.hasFocus = function () { return document.visibilityState == 'visible'; } }
Kent
3

Einfaches Javascript-Snippet

Ereignisbasiert:

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>

Intervallpoolbasiert:

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
quelle
Ich mag diese Antwort wegen der ereignisbasierten Lösung . Imho, es sollte immer der bevorzugte Weg sein.
quasi
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);
});​

Prüfung

AKTUALISIEREN:

Ich werde es beheben, aber IE funktioniert nicht sehr gut

Test Update

andres descalzo
quelle
Anscheinend wird beim Wechseln der Registerkarten keine Unschärfe ausgelöst. :(
Jethro Larson