Детектор фокуса вкладки — что страница записывает, когда вы уходите
Проверка…
Читаем, что этот документ сообщает о собственной видимости и фокусе.
Эта страница выполняет прямо в вашем браузере ту же проверку фокуса и видимости, что и страница онлайн-теста или прокторинга. Переключите вкладку, кликните в другое окно или сверните это — и посмотрите, что именно попадает в запись. Ничего не загружается на сервер: все показания ниже остаются в этой вкладке.
Журнал событий
Переключите вкладку, кликните в другое окно или сверните это — затем вернитесь.
Показания
| # | Время | Событие | Записанное состояние | Отсутствие |
|---|---|---|---|---|
| Пока пусто. Перейдите на другую вкладку или кликните в другое окно, затем вернитесь. | ||||
Что читает этот тест
Каждый браузер открывает два независимых показания. document.visibilityState сообщает, является ли эта вкладка отображаемой, а document.hasFocus() — получает ли именно этот документ нажатия клавиш. Ни одно не требует разрешения и ни одно нельзя отключить.
Это не одно и то же. Переход на другую вкладку делает страницу скрытой. А клик по второму окну браузера, мессенджеру или терминалу оставляет вкладку видимой, но забирает фокус — страница становится без фокуса, а не скрытой.
Платформы тестирования обычно пишут оба показания, считают их отдельно и засекают длительность каждого отсутствия. Таблица ниже показывает ровно ту запись, которую они бы построили.
Что это вызывает
- Переход на другую вкладку — срабатывает
visibilitychange, состояние становится hidden. Записывается везде, включая телефоны. - Сворачивание окна, блокировка экрана или засыпание телефона — тоже считается скрытием.
- Клик по другому окну или приложению — второе окно браузера, редактор, мессенджер, панель поиска или лаунчер. Вкладка остаётся видимой; вместо этого срабатывает событие
blurокна. - Открытие инструментов разработчика в отдельном окне — считается сменой окна, поэтому срабатывает blur.
- Заморозка или выгрузка вкладки браузером ради экономии памяти — в Chromium срабатывают
freezeиpagehide. - Закрытие или перезагрузка страницы — срабатывает
pagehide, именно этим событием платформы закрывают незавершённую попытку.
Перед онлайн-тестированием
Если тест предупреждает, что уход со страницы записывается, стоит заранее понять, что это на самом деле значит.
- Откройте эту страницу в том браузере, в котором действительно будете проходить тест, и оставьте её открытой.
- Перейдите на другую вкладку и сразу вернитесь. Обратите внимание: журнал записал событие hidden и точное число секунд.
- Теперь вместо этого кликните в другое окно — мессенджер или редактор. В журнале появится событие blur, а вкладка ни разу не была скрытой.
- Включите блокирующий экран, чтобы увидеть, что страница теста показывает в момент вашего ухода. Многие платформы показывают ровно это.
- Помните о случайных срабатываниях: баннер уведомления, окно менеджера паролей или лаунчер горячих клавиш тоже попадут в запись.
Знать, что записывается, — не то же самое, что обойти это. Страница говорит вам, каково показание; как его трактует платформа — решать ей.
Как выводится результат
В фокусе — visibilityState равно visible, а hasFocus() — true. Вкладка на экране и принимает ваши нажатия.
Без фокуса — по-прежнему видима, но фокус ушёл в другое окно или приложение. Вы смотрите на эту вкладку, а печатаете в другом месте, либо сверху лежит чужое окно.
Скрыта — вкладка вообще не отрисовывается: впереди другая вкладка, окно свёрнуто или экран устройства выключен.
Таймер отсутствия запускается с первого события, забравшего фокус, и останавливается, когда оба показания снова становятся истинными, — поэтому blur, перешедший в переключение вкладки, считается одним непрерывным отсутствием.
Чего он не видит
Ни одно из этих показаний не говорит, куда вы ушли. Страница узнаёт лишь то, что перестала быть активной, и на сколько — но не какая это вкладка, какое приложение и что было на экране.
Всё, что происходит вне браузера и не забирает фокус клавиатуры, для этого API невидимо: событию просто неоткуда взяться. Сюда относятся второе физическое устройство, распечатанный лист или другой человек в комнате.
Само по себе число ничего не доказывает. Уведомление, забравшее фокус, панель экранного диктора, запрос на обновление системы и осознанное переключение вкладки дают одно и то же событие.
Серьёзный прокторинг не полагается только на это. Камера, микрофон, демонстрация экрана и устанавливаемые защищённые браузеры видят гораздо больше, чем веб-страница, — о другом показании, которое страница может снять не спрашивая, см. тест обнаружения внешнего монитора.
Приватность
Страница статическая. Ни аналитики, ни cookie, ни локального хранилища; после загрузки она не делает ни одного сетевого запроса.
Каждый счётчик и каждая отметка времени вычисляются внутри вашей вкладки и исчезают, как только вы её закроете. Перезагрузка сбрасывает всё.
Вы можете прочитать это целиком: один файл JavaScript, ссылка в подвале.
Поддержка браузеров
visibilitychange и document.hasFocus() работают во всех современных браузерах, на компьютере и на телефоне, без разрешений и без требования защищённого источника.
freeze и resume есть только в Chromium и срабатывают, когда браузер приостанавливает фоновую вкладку ради экономии памяти. Остальные браузеры о них просто не сообщают.
В iOS переключение приложений фиксируется как скрытие, а не как потеря фокуса, потому что в фон уходит весь браузер. Различие между ними существует только там, где есть окна.
Частые вопросы
Может ли сайт определить, что я переключил вкладку?
Да, и разрешения для этого не нужны. Событие visibilitychange срабатывает в тот же миг, когда ваша вкладка перестаёт быть отображаемой, а document.visibilityState возвращает hidden, пока вы не вернётесь. Это реализовано во всех современных браузерах, включая мобильные. Настройки, которая скрыла бы это от страницы, не существует.
Отличает ли онлайн-тест переключение вкладки от открытия другого приложения?
Да. Переключение вкладки делает страницу скрытой; клик по другому окну или приложению оставляет её видимой, но забирает фокус клавиатуры, из-за чего срабатывает событие blur. Платформа, записывающая оба, различает их, и эта страница показывает каждое отдельно, чтобы вы сами увидели разницу.
Знает ли онлайн-тест, на какую вкладку или в какое приложение я ушёл?
Нет. Браузер сообщает странице только то, что она перестала быть активным документом, и сколько это длилось. Пункт назначения — другая вкладка, другая программа, заблокированный экран — никогда не раскрывается. Всё, что подробнее, требует демонстрации экрана или установленного защищённого браузера; и то и другое заметно и требует вашего согласия.
Считается ли снимок экрана уходом со страницы?
Это целиком зависит от способа. Горячая клавиша, которую обрабатывает сама операционная система без собственного интерфейса, не вызывает ничего, потому что браузер не теряет фокус. А всё, что открывает выбор области, панель или окно предпросмотра, фокус забирает, и это записывается как blur. Попробуйте оба варианта на этой странице и посмотрите журнал.
Почему счётчик вырос, хотя я не переключал вкладки?
Фокус забирают куда больше вещей, чем принято думать: баннеры уведомлений, всплывающие окна менеджера паролей, запрос на обновление системы, лаунчер горячих клавиш или инструменты разработчика, открытые в отдельном окне. Все они дают событие blur, неотличимое от намеренного переключения.
Можно ли отключить это определение в настройках браузера?
Нет. Page Visibility API — часть самого документа, а не разрешение, поэтому отзывать нечего. Его блокировка сломала бы законные сценарии: паузу видео, остановку анимации и таймеров в фоновых вкладках.
Спасает ли второй монитор от записи переключений?
Нет. Перевести взгляд на второй экран ничего не меняет, но клик по окну на нём забирает фокус клавиатуры у этой вкладки и вызывает точно такой же blur, как и на одном экране. Виден ли странице сам второй экран — отдельный вопрос, и его разбирает тест обнаружения внешнего монитора.
Отправляется ли что-нибудь из этого на сервер?
Нет. Страница статическая, без аналитики и cookie, и после загрузки не делает сетевых запросов. Каждое показанное событие и каждый таймер вычисляются внутри вашей вкладки и отбрасываются при её закрытии.