JavaScript / jQuery: Перевірте, чи вікно має фокус


80

Як перевірити, чи браузер має фокус?


Дивіться також stackoverflow.com/questions/483741/…, який також може відповісти на це питання.
Alexander Bird

15
Спробуйте document.hasFocus(), що повертає логічне значення. Він вбудований в специфікацію, тому це можна зробити без jQuery.
Braden Best

Для тих, хто хоче перевірити видимість сторінок (що не є таким самим, як фокус), будь ласка, перевірте API видимості сторінок для отримання додаткової інформації.
tsh

Відповіді:


79

Я не тестував цього в інших браузерах, але, схоже, це працює в Webkit. Я дозволю вам спробувати IE. : o)

Спробуйте: http://jsfiddle.net/ScKbk/

Після натискання, щоб почати інтервал, змініть фокус вікна браузера, щоб побачити зміну результату. Знову ж таки, протестовано лише у Webkit.

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 - Має бути IE? У Webkit та Firefox будь-яка активація вікна викликає фокус. Цікаво, чи існує обхідний шлях для IE. Крім того, ви тестували на своїй сторінці? Може, є проблема, тому що jsFiddle використовує кадри?
user113716

Chrome насправді. Після подальшого тестування мій перший коментар може бути помилковим - розбивання клавіші табуляції здається більш послідовним.
jball

@jball - Я здогадуюсь, що клавіша табуляції порушує це, оскільки jsFiddle має багато вхідних елементів в інших кадрах. Позбавтеся від рамок, і я впевнений, що це буде працювати трохи краще для вас.
user113716

Я вважаю, що кожен фрейм має свій власний windowоб’єкт, тому, якщо ви хочете використовувати фрейми, вам, мабуть, просто потрібно буде включити сценарій у кожен з них.
user113716

4
Використовуйте window.topдля перевірки верхнього вікна.
Mårten Wikström,

160

використовуйте метод hasFocus документа. Ви можете знайти детальний опис і приклад тут: метод hasFocus

EDIT: Додана скрипка 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
Я спробував приклад із наведеного вище посилання, і він добре працював в IE7 +, Chrome та FF4. +1 для вас.
Джозеф Луст

1
Чудова маленька функція, працює набагато краще, ніж інші еквіваленти jQuery, з якими я стикався.
Heath

3
Більш корисно, ніж прийнята відповідь, у мене були проблеми із завантаженням таймера, коли вікно було нефокусоване.
Кокос,

Opera не підтримує цього. Заспокійливим фактом є те, що вони перемикають механізм візуалізації на Webkit :)
Нікола Петканський

6
Тим часом ви можете використати щось подібне, щоб отримати функціональність в Opera: if(typeof document.hasFocus === 'undefined') { document.hasFocus = function () { return document.visibilityState == 'visible'; } }
Кент,

3

Простий фрагмент JavaScript

На основі події:

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>

Інтервальний пул на основі:

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>


Ця відповідь мені подобається через рішення, яке базується на подіях . Імхо, це завжди повинен бути кращий спосіб.
квазі

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

тест

ОНОВЛЕННЯ:

Я виправлю це, але IE працює не дуже добре

оновлення тесту


Мабуть, розмиття не спрацьовує при перемиканні вкладки. :(
Джетро Ларсон,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.