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.