Як визначити, коли вкладка сфокусована чи ні в Chrome за допомогою Javascript?


75

Мені потрібно знати, переглядає користувач на даний момент вкладку чи ні в Google Chrome. Я намагався використовувати розмиття подій та фокусування, прив’язане до вікна, але, здається, лише розмиття працює коректно.

window.addEventListener('focus', function() {
  document.title = 'focused';
});

window.addEventListener('blur', function() {
  document.title = 'not focused';
});

Фокусна подія працює дивно, лише іноді. Якщо я перейду на іншу вкладку і назад, подія фокусу не активується. Але якщо я натисну на адресний рядок, а потім повернуся на сторінку, це буде. Або, якщо я перейду на іншу програму, а потім повернуся до Chrome, вона активується, якщо вкладка в даний момент зосереджена.


Ви намагалися приєднати ці події docmentзамість window?
Крозін

Я не впевнений, чи впливає це на виявлення подій, але window.focusдія вимкнена (або принаймні помилка) у Chrome. Дивіться тут і тут, щоб дізнатися більше.
brahn

Також не працює з документом, і це стосується події фокусування, а не дії фокусування. Думаю, я зміню свій підхід до цього і зміню подію на наведення курсору миші або прокрутку вікна. Для цього сценарію це доречно.
вступ

Код, про який ви питаєте, чудово працює в Chrome станом на 2011 рік. Рішення не працює.
ніндзягецко

Відповіді:


131

Оновлення 2015 року: Новий спосіб HTML5 з API видимості (взято з коментаря Blowsie):

document.addEventListener('visibilitychange', function(){
    document.title = document.hidden; // change tab text for demo
})

Код, який надає оригінальний плакат (у питанні), зараз працює станом на 2011 рік:

window.addEventListener('focus', function() {
    document.title = 'focused';
});

window.addEventListener('blur', function() {
    document.title = 'not focused';
});

редагувати : станом на кілька місяців пізніше в Chrome 14, це все одно буде працювати, але користувач повинен взаємодіяти зі сторінкою, принаймні один раз клацнувши в будь-якому місці вікна. Простого прокручування і цього недостатньо, щоб зробити цю роботу. Це window.focus()також не робить цю роботу автоматично. Якщо хтось знає спосіб обходу, будь ласка, згадайте.


1
Спосіб змусити це працювати без необхідності користувачеві натискати десь спочатку - це додати "window.focus ()" до події window.onload. Побічним ефектом цього є те, що якщо вікно є ціллю посилання і вже було відкрите за поточним вікном, воно буде винесене на передню частину. Зверніть увагу, що це рішення виявляє лише втрату фокусу, а не те, що воно було спричинене перемиканням вкладок. Наприклад, якщо втрата фокусу відбулася через натискання користувачем внутрішнього фрейму, ви повинні усунути це:
SPitBalls.com

<iframe ... onmouseover = "iframeMouse (true)" onmouseout = "iframeMouse (false)"> </iframe>
SPitBalls.com

функція iframeMouse (over) {oif = over; } window.addEventListener ('blur', function () {document.title = oif? "iframe focus": "not focus";});
SPitBalls.com

5
Щоб отримати більш поглиблену надійну відповідь, див. Це. forums.greensock.com/topic/…
Blowsie

2
Використовуйте document.visibilityStateдля отримання поточного стану видимості
Олег


2

Зрештою, це може спрацювати, мені стало цікаво і я написав такий код:

...
setInterval ( updateSize, 500 );
function updateSize(){
  if(window.outerHeight == window.innerHeight){
    document.title = 'not focused';             
  } else {
    document.title = 'focused';
  }

  document.getElementById("arthur").innerHTML = window.outerHeight + " - " + window.innerHeight;
}
...
<div id="arthur">
  dent
</div>

Цей код робить точно, що ви хочете, але потворно. Справа в тому, що Chrome, здається, час від часу ігнорує зміну заголовка (при переході на вкладку та утримуванні миші протягом 1 секунди, здається, завжди створюється цей ефект).

Ви отримаєте різні значення на екрані, але ваш заголовок не зміниться.

висновок: Що б ви не робили, не довіряйте результату при його тестуванні!


Назва миттєво змінюється для мене. Якщо я змінив події на наведення та наведення миші, я отримую миттєві результати.
вступ

У будь-якому випадку, дякую за частину (window.outerHeight == window.innerHeight). Для цього конкретного проекту мені потрібно лише знати, чи користувач зараз зосереджений чи ні. Не потрібно постійно перевіряти, і ваш код працює.
вступ

2

Для тих, хто хоче поміняти заголовки сторінок розмитими, а потім повернутися до початкового заголовка сторінки на фокусі:

// Swapping page titles on blur
var originalPageTitle = document.title;

window.addEventListener('blur', function(){
    document.title = 'Don\'t forget to read this...';
});

window.addEventListener('focus', function(){
    document.title = originalPageTitle;
});


0

Це може працювати з JQuery

$(function() {
    $(window).focus(function() {
        console.log('Focus');
    });

    $(window).blur(function() {
        console.log('Blur');
    });
});

Я думаю, це не допоможе, тому що, як він повідомив, браузер НЕ запускає функцію події, яку ви прикріпили в "розмитті". Так як у вашому прикладі і код console.log('Blur');НЕ буде викликаний у деяких ситуаціях.
psulek

-2

У chrome ви можете запустити фоновий скрипт з таймаутом менше 1 секунди, а коли вкладка не має фокусу, chrome запускатиме його лише кожну секунду. Приклад;

Це не працює у Firefox чи Opera. Не знаю про інші браузери, але я сумніваюсь, що це теж працює.

var currentDate = new Date();
var a = currentDate.getTime();

function test() {
    var currentDate = new Date();
    var b = currentDate.getTime();
var c = b - a;
    if (c > 900) {
        //Tab does not have focus.
    } else {
        //It does
    }
    a = b;
    setTimeout("test()",800);
}



setTimeout("test()",1);

2
Мені не подобається ідея використовувати інтервали для чогось, що має бути рівним. І зауважте, ви повинні використовувати setTimeout(test, 800). Якщо ви дасте йому рядок, він це зробить eval(), що набагато повільніше.
фент
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.