JavaScript / jQuery: sprawdź, czy fokus ma okno


80

Jak sprawdzić, czy przeglądarka ma fokus?


Zobacz także stackoverflow.com/questions/483741/…, które również mogą odpowiedzieć na to pytanie.
Alexander Bird

15
Try document.hasFocus(), która zwraca wartość logiczną. Jest wbudowany w specyfikację, więc można to zrobić bez jQuery.
Braden Best

Dla kogoś, kto chce sprawdzić widoczność stron (która nie jest tym samym, co fokus), sprawdź interfejs API widoczności strony, aby uzyskać więcej informacji.
tsh

Odpowiedzi:


79

Nie testowałem tego w innych przeglądarkach, ale wydaje się, że działa w Webkit. Pozwolę ci wypróbować IE. : o)

Wypróbuj: http://jsfiddle.net/ScKbk/

Po kliknięciu, aby rozpocząć interwał, zmień fokus okna przeglądarki, aby zobaczyć zmianę wyniku. Ponownie przetestowany tylko w Webkicie.

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 - czy musi to być IE? W Webkit i Firefox każda aktywacja okna wyzwala fokus. Zastanawiam się, czy istnieje obejście dla IE. Czy testowałeś też swoją stronę? Może pojawił się problem, ponieważ jsFiddle używa ramek?
user113716

Właściwie Chrome. Po dalszych testach mój pierwszy komentarz może być błędny - złamanie klawisza tabulacji wydaje się być bardziej spójne.
jball

@jball - zgaduję, że klawisz tabulatora go psuje, ponieważ jsFiddle ma wiele elementów wejściowych w innych ramkach. Pozbądź się ramek, a założę się, że zadziała trochę lepiej.
user113716

Uważam, że każda ramka ma swój własny windowobiekt, więc jeśli miałbyś używać ramek, prawdopodobnie musiałbyś po prostu dołączyć skrypt do każdej z nich.
user113716

4
Służy window.topdo sprawdzania najwyższego okna.
Mårten Wikström

160

użyj metody hasFocus dokumentu. Szczegółowy opis i przykład można znaleźć tutaj: metoda hasFocus

EDYCJA: Dodano skrzypce 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
Wypróbowałem przykład z powyższego linku i działał dobrze w IE7 +, Chrome i FF4. +1 dla Ciebie.
Joseph Lust

1
Świetna mała funkcja, działa znacznie lepiej niż inne odpowiedniki jQuery, z którymi się spotkałem.
Heath

3
Bardziej użyteczna niż zaakceptowana odpowiedź, miałem problemy z ładowaniem timera, gdy okno było nieostre.
Kokos

Nie jest to obsługiwane przez Operę. Uspokajający jest fakt, że są w trakcie przełączania silnika renderującego na Webkit :)
Nikola Petkanski

6
W międzyczasie możesz użyć czegoś takiego, aby uzyskać funkcjonalność w Operze: if(typeof document.hasFocus === 'undefined') { document.hasFocus = function () { return document.visibilityState == 'visible'; } }
Kent

3

Prosty fragment kodu JavaScript

Na podstawie wydarzenia:

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>

Na podstawie puli interwałowej:

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>


Podoba mi się ta odpowiedź ze względu na rozwiązanie oparte na zdarzeniach . Imho, zawsze powinien być preferowany sposób.
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);
});​

test

AKTUALIZACJA:

Naprawię to, ale IE nie działa zbyt dobrze

aktualizacja testowa


Najwyraźniej rozmycie nie uruchamia się podczas przełączania kart. :(
Jethro Larson
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.