JavaScript / jQuery: sprawdź, czy fokus ma okno

80

Jak sprawdzić, czy przeglądarka ma fokus?

Pręt
źródło
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);
});​
user113716
źródło
@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);
guma
źródło
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>

F. Hauri
źródło
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

andres descalzo
źródło
Najwyraźniej rozmycie nie uruchamia się podczas przełączania kart. :(
Jethro Larson