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


80

Wie testen Sie, ob der Browser den Fokus hat?


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);
});​

@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);

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>


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


Anscheinend wird beim Wechseln der Registerkarten keine Unschärfe ausgelöst. :(
Jethro Larson
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.