7

Как определить, что окно браузера в данный момент не активно?

5

Проблема: У меня есть JavaScript, который выполняет некоторые действия периодически. Когда пользователь не находится на сайте (т.е. окно или вкладка не имеют фокуса), было бы неплохо, чтобы скрипт не выполнялся.

Есть ли способ реализовать это с помощью JavaScript?

Пример, с которого я ориентируюсь: в чате Gmail звуковой сигнал воспроизводится только если активное окно не является окном чата.

5 ответ(ов)

1

Я бы использовал jQuery, потому что тогда вам нужно всего лишь сделать следующее:

$(window).blur(function(){
  // ваш код здесь
});
$(window).focus(function(){
  // ваш код
});

Или, по крайней мере, это сработало для меня.

0

Я начал с использования ответа в вики-сообществе, но потом понял, что он не отслеживает события alt-tab в Chrome. Это связано с тем, что используется первый доступный источник событий, а в данном случае это API видимости страницы, который в Chrome, похоже, не отслеживает изменение фокуса из-за переключения между окнами.

Я решил немного изменить скрипт, чтобы отслеживать все возможные события изменения фокуса страницы. Вот функция, которую вы можете вставить:

function onVisibilityChange(callback) {
    var visible = true;

    if (!callback) {
        throw new Error('не предоставлен колбэк');
    }

    function focused() {
        if (!visible) {
            callback(visible = true);
        }
    }

    function unfocused() {
        if (visible) {
            callback(visible = false);
        }
    }

    // Стандарты:
    if ('hidden' in document) {
        visible = !document.hidden;
        document.addEventListener('visibilitychange',
            function() {(document.hidden ? unfocused : focused)()});
    }
    if ('mozHidden' in document) {
        visible = !document.mozHidden;
        document.addEventListener('mozvisibilitychange',
            function() {(document.mozHidden ? unfocused : focused)()});
    }
    if ('webkitHidden' in document) {
        visible = !document.webkitHidden;
        document.addEventListener('webkitvisibilitychange',
            function() {(document.webkitHidden ? unfocused : focused)()});
    }
    if ('msHidden' in document) {
        visible = !document.msHidden;
        document.addEventListener('msvisibilitychange',
            function() {(document.msHidden ? unfocused : focused)()});
    }
    // IE 9 и ниже:
    if ('onfocusin' in document) {
        document.onfocusin = focused;
        document.onfocusout = unfocused;
    }
    // Все остальные:
    window.onpageshow = window.onfocus = focused;
    window.onpagehide = window.onblur = unfocused;
};

Используйте ее следующим образом:

onVisibilityChange(function(visible) {
    console.log('страница сейчас', visible ? 'в фокусе' : 'не в фокусе');
});

Эта версия слушает все различные события видимости и вызывает колбэк, если какое-либо из них вызывает изменение. Обработчики focused и unfocused гарантируют, что колбэк не будет вызван несколько раз, если несколько API поймают одно и то же изменение видимости.

0

На GitHub доступна отличная библиотека:

https://github.com/serkanyersen/ifvisible.js

Пример использования:

// Если страница сейчас видима
if( ifvisible.now() ){
  // Показать всплывающее окно
  openPopUp();
}

Я протестировал версию 1.0.1 во всех браузерах, которые у меня есть, и могу подтвердить, что она работает с:

  • IE9, IE10
  • Firefox 26.0
  • Chrome 34.0

... и, вероятно, со всеми более новыми версиями.

Но не совсем корректно работает с:

  • IE8 — всегда указывает, что вкладка/окно активно (.now() всегда возвращает true в моем случае)
0

Ваш код для обработки новых сообщений в Comet Chat выглядит вполне неплохо, однако есть несколько моментов, которые стоит учесть. Вы используете проверку document.hasFocus(), чтобы определить, находится ли окно приложения в фокусе, после чего воспроизводите звук и изменяете заголовок страницы.

Вот несколько рекомендаций для улучшения:

  1. Звук: Убедитесь, что у вас есть способ остановить звук, если пользователь уже находится в приложении. Возможно, стоит использовать более удобный метод для управления аудио.

  2. Асинхронность: Если audio.play() или audio.stop() являются асинхронными операциями, вам может понадобиться дождаться их завершения, прежде чем изменять заголовок.

  3. Проверка наличия нового сообщения: Убедитесь, что new_message определено. Если null, это может вызвать ошибки в будущем.

  4. Обновление заголовка: Если вы получаете множество сообщений, каждый раз изменять заголовок может быть не самым лучшим решением. Возможно, вместо простой замены названия стоит добавлять к нему количество новых сообщений.

Вот предложенная версия вашего кода с учетом этих моментов:

if(new_message){
    if(!document.hasFocus()){
        audio.play().catch(error => console.error("Error playing audio:", error)); // Обрабатываем возможные ошибки
        document.title = "У вас новые сообщения";
    } else {
        audio.pause(); // Или используйте другой метод для остановки звука
        document.title = "Имя приложения"; // Верните обратно оригинальное имя
    }
}

Если вы ожидаете частую покупку новых сообщений, возможно, стоит подумать о механизме, который будет показывать уведомления, даже если окно с приложением закрыто, например, используя Notifications API. Надеюсь, это поможет улучшить ваш код!

0

Этот код работает во всех современных браузерах и позволяет отслеживать изменения видимости страницы: при переключении между вкладками, при смене окон с помощью Alt+Tab и при развертывании другого приложения из панели задач.

Вот краткое объяснение кода:

  1. Определение события видимости: В зависимости от поддержки различных свойств (hidden) в объекте document определяется имя события (visibilitychange, msvisibilitychange, mozvisibilitychange или webkitvisibilitychange).

  2. Добавление слушателей событий: Если событие определено, устанавливается обработчик handleChange с помощью addEventListener. Также добавляются обработчики для событий фокуса и потери фокуса, чтобы отслеживать переключение между вкладками.

  3. Инициализация состояния: Если API видимости страницы поддерживается, вызывается функция handleChange для установки начального состояния (visible) на основе текущего состояния страницы.

  4. Функция обработки событий handleChange: Эта функция обновляет состояние видимости и выводит соответствующее сообщение в консоль. Если страница становится невидимой, логируется сообщение "Out...", а если снова видима — "In...".

Таким образом, данный код позволяет эффективно отслеживать, когда пользователь уходит со страницы и когда возвращается, что может быть полезно для управления состоянием и производительностью веб-приложений.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь