visibilityChange или как отследить виден ли таб с вашей страницей в браузере пользователя в текущий момент.

В браузерах всегда не хватало какого-нибудь индикатора того, находится ли страница в активном табе.

Вот несколько примеров того, как это можно использовать:

  • У вас на сайте есть видео и вы хотите поставить его на паузу, пока пользователь сделал неактивным таб с вашей страницей.
  • Другой типовой пример: изменить title и favicon страницы, когда она скрыта.
  • Или, например, оповестить пользователя о новых комментариях или других событиях, если ваш сайт находится в неактивном табе (так делают многие соц. сети)

Начнем с демо, а потом посмотрим, зачем это нужно и как это работает.

Запустите видео и перейдите на соседнюю вкладку браузера. Видео должно остановиться (если у Вас поддерживается visibilityChange)

visibilitychange С недавнего времени в новых (нормальных) браузерах появилось

Page Visibility API. Давайте посмотрим, как это работает. В целом, все просто:

JS

document.addEventListener('visibilitychange', function(e) {
  console.log('hidden:' + document.hidden,
              'state:' + document.visibilityState)
}, false);

document.visibilityState — может быть "visible", "hidden" или "prerender". C visible и hidden все понятно. prerender — значит, что содержимое страницы в настоящее время находится в состоянии отрисовки. Документ может инициализироваться в этом состоянии, но никогда не сможет перейти к состоянию «prerender» от другого значения. Производители браузеров не исключают добавления новых значений document.visibilityState в будущем.

document.hiddentrue или false соответственно.

Не все так безоблачно. Т.к. API и стандарт сырые, вот с чем приходится сталкиваться сегодня (2013):

  • событие visibilitychange, в зависимости от браузера, называется "visibilitychange", "mozvisibilitychange", "msvisibilitychange", "webkitvisibilitychange".
  • поле document.visibilityState, в зависимости от браузера, называется "visibilityState", "mozVisibilityState", "msVisibilityState", "webkitVisibilityState".
  • поле document.hidden, в зависимости от браузера, называется "hidden", "mozHidden", "msHidden", "webkitHidden". Кошмар… Дорогой друг, если ты читаешь эту статью и используешь visibilitychange api этак в 2015-ом году, можешь пропустить весь последующий говнокод. А пока, в связи с этим переходным периодом пока надо писать что-то типа:

JS

var hidden, state, visibilityChange; 
if (typeof document.hidden !== "undefined") {
  hidden = "hidden";
  visibilityChange = "visibilitychange";
  state = "visibilityState";
} else if (typeof document.mozHidden !== "undefined") {
  hidden = "mozHidden";
  visibilityChange = "mozvisibilitychange";
  state = "mozVisibilityState";
} else if (typeof document.msHidden !== "undefined") {
  hidden = "msHidden";
  visibilityChange = "msvisibilitychange";
  state = "msVisibilityState";
} else if (typeof document.webkitHidden !== "undefined") {
  hidden = "webkitHidden";
  visibilityChange = "webkitvisibilitychange";
  state = "webkitVisibilityState";
}

// Add a listener that constantly changes the title
document.addEventListener(visibilityChange, function() {
  console.log('state = ' + document[state], 'hidden = ' + document[hidden]);
}, false);

А вот и код демки в начале статьи

HTML

<div>
  <video id="videoElement" controls width="400" height="300">
    <source src="/blogdemo/video/chrome.webm" type="video/webm" />
    <source src="/blogdemo/video/chrome.ogv" type="video/ogg" />
    <source src="/blogdemo/video/chrome.mp4" type="video/mp4; codecs='avc1.42E01E, mp4a.40.2'" />
  </video>
</div>

JS

// видео изначально стоит на паузе (true в ковычках потому-что это sessionStorage)
sessionStorage.isPaused = "true";

// зададим тестовые переменные для hidden property и события visibility change 
var hidden, visibilityChange;
if (typeof document.hidden !== "undefined") {
  hidden = "hidden";
  visibilityChange = "visibilitychange";
} else if (typeof document.mozHidden !== "undefined") {
  hidden = "mozHidden";
  visibilityChange = "mozvisibilitychange";
} else if (typeof document.msHidden !== "undefined") {
  hidden = "msHidden";
  visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
  hidden = "webkitHidden";
  visibilityChange = "webkitvisibilitychange";
}

var videoElement = document.getElementById("videoElement");

// если страница скрыта - поставить видео на паузу
// если страница активна - продолжить воспроизведение
function handleVisibilityChange() {
  if (document[hidden]) {
    videoElement.pause();
  } else if (sessionStorage.isPaused !== "true") {
    videoElement.play();
  }
}

// предупредить, если браузер не поддерживает addEventListener или Page Visibility API
if (typeof document.addEventListener === "undefined" || typeof hidden === "undefined") {
  alert("Демо требует нормального браузера с поддержкой Page Visibility API.");
} else {

  // обработка visibilityChange
  document.addEventListener(visibilityChange, handleVisibilityChange, false);

  videoElement.addEventListener("pause", function () {
    if (!document[hidden]) {
      sessionStorage.isPaused = "true";
    }
  }, false);

  videoElement.addEventListener("play", function () {
    sessionStorage.isPaused = "false";
  }, false);

  // установить title страницы
  videoElement.addEventListener("timeupdate", function () {
    document.title = Math.floor(videoElement.currentTime) + " сек";
  }, false);
}

Отмечено как: , , ,
8 comments on “visibilityChange или как отследить виден ли таб с вашей страницей в браузере пользователя в текущий момент.
  1. IE к версии 15 обещают саппорт?

  2. Кстати, если не включать видео и переключится на таб видео включится)

  3. Алексей:

    Спасибо за информацию и пример.
    Только в вашем примере, если не запускать видео, а после загрузки страницы, переключиться на другую вкладку и вернуться, то видео автоматически запустится. :)
    Мелочи, но все-таки маленький недочет для завершенного модуля.

  4. Vital:

    решал подобную задачу, используя события onfocus и onblur

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax

*

* Copy This Password *

* Type Or Paste Password Here *

Проект создан в GanttPRO
Спасибо за лайк в FACEBOOK
Подписывайтесь на новости вконтакте
Последние статьи от html5.by