У меня есть JavaScript, который делает деятельность периодически. Когда пользователь не смотрит на сайт (то есть окно или вкладка не имеют фокуса), было бы неплохо не запускаться.
Есть ли способ сделать это с помощью JavaScript?
Мой ориентир: Gmail Chat воспроизводит звук, если окно, которое вы используете, не активно.
javascript
browser
focus
window
Люк Франкл
источник
источник
requestAnimationFrame
API или используйте современную функцию, которая уменьшает частотуsetTimeout
/,setInterval
когда окно не видно (например, 1 секунда в Chrome).blur
/focus
в браузерах, которые его не поддерживают.blur
/focus
события ... которые будут иметь ограниченное использование, хотя окно может быть неактивным, но полностью или частично видимым (на некоторых панелях задач также есть значки предварительного просмотра, которые люди ожидают, что они будут продолжать обновлено).Ответы:
С момента написания этого ответа новая спецификация достигла статуса рекомендации благодаря W3C. Page Visibility API (на MDN ) теперь позволяет нам более точно определить , когда страница скрыта от пользователя.
Текущая поддержка браузера:
Следующий код возвращается к менее надежному методу размытия / фокусировки в несовместимых браузерах:
onfocusin
иonfocusout
которые необходимы для IE 9 и нижней части , в то время как все другие используютonfocus
иonblur
для IOS, которая использует кромеonpageshow
иonpagehide
.источник
focusin
иfocusout
от iframe до верхнего окна. Для новых браузеров, вы просто должны обрабатыватьfocus
иblur
событие на каждый Iframe вwindow
объекте. Вы должны использовать обновленный код, который я только что добавил, который будет по крайней мере покрывать эти случаи в новых браузерах.Я бы использовал jQuery, потому что тогда все, что вам нужно сделать, это:
Или, по крайней мере, это сработало для меня.
источник
window
он потеряет фокус, что правильно, но в зависимости от того, что вы хотите, может быть не то, что вам нужно.Есть 3 типичных метода, используемых, чтобы определить, может ли пользователь видеть страницу HTML, однако ни один из них не работает идеально:
W3C Page Visibility API должен делать это (поддерживается начиная с: Firefox 10, MSIE 10, Chrome 13). Однако этот API вызывает события только тогда, когда вкладка браузера полностью переопределена (например, когда пользователь переключается с одной вкладки на другую). API не вызывает события, когда видимость не может быть определена со 100% точностью (например, Alt + Tab для переключения на другое приложение).
Использование методов фокусировки / размытия дает много ложных срабатываний. Например, если пользователь отображает меньшее окно в верхней части окна браузера, окно браузера теряет фокус (
onblur
поднятый), но пользователь все еще может его видеть (поэтому его все равно необходимо обновить). Смотрите также http://javascript.info/tutorial/focusЧтобы улучшить несовершенное поведение, описанное выше, я использую комбинацию из 3 методов: W3C Visibility API, затем методы фокусировки / размытия и пользовательской активности, чтобы уменьшить вероятность ложных срабатываний. Это позволяет управлять следующими событиями:
Вот как это работает: когда документ теряет фокус, пользовательская активность (например, перемещение мыши) в документе отслеживается, чтобы определить, является ли окно видимым или нет. Вероятность видимости страницы обратно пропорциональна времени последнего пользовательского действия на странице: если пользователь долгое время не выполняет никаких действий с документом, скорее всего, страница не видна. Приведенный ниже код имитирует API видимости страницы W3C: он ведет себя так же, но имеет небольшой процент ложных срабатываний. Он имеет преимущество быть мультибраузером (протестировано на Firefox 5, Firefox 10, MSIE 9, MSIE 7, Safari 5, Chrome 9).
Поскольку в настоящее время не существует работающего кросс-браузерного решения без ложных срабатываний, вам следует подумать дважды об отключении периодической активности на вашем веб-сайте.
источник
На GitHub есть аккуратная библиотека:
https://github.com/serkanyersen/ifvisible.js
Пример:
Я протестировал версию 1.0.1 на всех моих браузерах и могу подтвердить, что она работает с:
... и, вероятно, все более новые версии.
Не полностью работает с:
.now()
всегда возвращаетсяtrue
для меня)источник
Использование: API видимости страницы
Могу ли я использовать ? http://caniuse.com/#feat=pagevisibility
источник
Я создаю чат Comet для своего приложения, и когда я получаю сообщение от другого пользователя, я использую:
источник
document.hasFocus()
это самый чистый способ сделать это. Все остальные способы, использующие API видимости или события, основанные на событиях или ищущие различные уровни пользовательской активности / отсутствия активности, становятся слишком сложными и полными крайних случаев и дыр. поместите его в простой интервал и создайте пользовательское событие при изменении результатов. Пример: jsfiddle.net/59utucz6/1Я начал с использования вики-ответа сообщества, но понял, что он не обнаруживает события alt-tab в Chrome. Это потому, что он использует первый доступный источник событий, и в данном случае это API видимости страницы, который в Chrome, похоже, не отслеживает alt-tabbing.
Я решил немного изменить сценарий, чтобы отслеживать все возможные события для изменения фокуса страницы. Вот функция, которую вы можете добавить:
Используйте это так:
Эта версия прослушивает все различные события видимости и запускает обратный вызов, если любое из них вызывает изменение.
focused
Иunfocused
обработчики убедитесь , что обратного вызова не вызывается несколько раз , если несколько API , поймать такое же изменение видимости.источник
document.hidden
и другоеdocument.webkitHidden
. Безelse
вif
конструкции мы получим 2 обратных вызовов правильные?Это действительно сложно. Похоже, не существует решения с учетом следующих требований.
Это происходит потому, что:
Учитывая эти ограничения, можно реализовать решение, которое объединяет - API видимости страницы - размытие окна / focus - document.activeElement
Это способно:
Когда в фрейме есть фокус, ваши события размытия / фокуса вообще не вызываются, и API видимости страницы не будет срабатывать при нажатии клавиши alt + tab.
Я основывался на решении @ AndyE и реализовал это (почти хорошее) решение здесь: https://dl.dropboxusercontent.com/u/2683925/estante-components/visibility_test1.html (извините, у меня возникли некоторые проблемы с JSFiddle).
Это также доступно на Github: https://github.com/qmagico/estante-components
Это работает на хром / хром. Это работает на firefox, за исключением того, что он не загружает содержимое iframe (есть идеи почему?)
В любом случае, чтобы решить последнюю проблему (4), единственный способ сделать это - прослушать события размытия / фокуса в iframe. Если у вас есть некоторый контроль над iframes, вы можете использовать для этого API postMessage.
https://dl.dropboxusercontent.com/u/2683925/estante-components/visibility_test2.html
Я до сих пор не проверил это с достаточным количеством браузеров. Если вы можете найти больше информации о том, где это не работает, пожалуйста, дайте мне знать в комментариях ниже.
источник
http://jsfiddle.net/ARTsinn/JTxQY/
источник
это работает для меня на Chrome 67, Firefox 67,
источник
вы можете использовать:
источник
В HTML 5 вы также можете использовать:
onpageshow
: Скрипт запускается, когда окно становится видимымonpagehide
: Скрипт, запускаемый, когда окно скрытоВидеть:
источник
Это адаптация ответа от Энди Э.
Это выполнит задачу, например, обновит страницу каждые 30 секунд, но только если страница видна и сфокусирована.
Если видимость не может быть обнаружена, то будет использоваться только фокус.
Если пользователь фокусирует страницу, то она сразу обновится
Страница не будет обновляться снова через 30 секунд после любого вызова ajax
источник
Для решения без jQuery проверьте Visibility.js, который предоставляет информацию о трех состояниях страницы
а также удобные обёртки для setInterval
Также доступен запасной вариант для старых браузеров (IE <10; iOS <7)
источник
Несколько более сложный способ - использовать
setInterval()
для проверки положения мыши и сравнить с последней проверкой. Если мышь не двигалась в течение заданного времени, пользователь, вероятно, бездействует.Это дает дополнительное преимущество: он говорит, находится ли пользователь в режиме ожидания, а не просто проверяет, не активировано ли окно.Как отмечали многие люди, это не всегда хороший способ проверить, простаивает ли окно пользователя или браузера, так как пользователь может даже не использовать мышь или смотреть видео, или что-то подобное. Я просто предлагаю один из возможных способов проверки на безделье.
источник
Для angular.js вот директива (на основе принятого ответа), которая позволит вашему контроллеру реагировать на изменение видимости:
Вы можете использовать его, как в следующем примере:,
<div react-on-window-focus="refresh()">
гдеrefresh()
находится функция области действия в области действия любого Контроллера.источник
Вот солидное, современное решение. (Короткая сладкая 👌🏽)
Это настроит слушателя на запуск при возникновении любого события видимости, которое может быть фокусом или размытием.
источник
Если вы хотите действовать на размытие всего браузера : как я уже говорил, если браузер теряет фокус, ни одно из предложенных событий не срабатывает. Моя идея состоит в том, чтобы считать в цикле и сбрасывать счетчик в случае возникновения события. Если счетчик достигает предела, я делаю location.href для другой страницы. Это также срабатывает, если вы работаете с dev-tools.
Это проект, успешно протестированный на FF.
источник