Несколько недель назад в MAX я имел удовольствие выступить с половиной презентации с Грегом Уилсоном на тему «Передовой HTML». Одним из API, который я продемонстрировал аудитории, был API Page Visibility . Как вы, вероятно, догадываетесь, это базовый API, позволяющий узнать, видна ли ваша страница конечному пользователю. У него пока нет полной поддержки, но это (еще раз) еще один отличный пример того, что вы можете добавить в свой код с относительной легкостью, чтобы улучшить работу ваших конечных пользователей.
Так насколько хорошо это поддерживается? Внедрение ниже взято из превосходного CanIUse и будет актуальным независимо от того, когда вы читаете эту запись в блоге:
Я думаю, что вы могли бы обобщить это как «хорошая поддержка рабочего стола, плохой мобильный». При этом API прост в использовании и не наносит никакого вреда вашему коду, если его не поддерживает конечный пользователь. Давайте рассмотрим простой пример.
В приведенном ниже сценарии у меня есть вызов AJAX, который запускается каждые (приблизительно) 2 секунды для получения новостной ленты с сервера.
<!DOCTYPE html> <html> <body> <div id="newswell"></div> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <script> var newsDiv; function getData() { $.ajax({url:"news.json"}).done(function(data) { newsDiv.innerHTML += "<p><b>Posted at " + new Date() + "<br/>" + data.message; //call it again in 2 seconds window.setTimeout(getData, 2000); }).fail(function(xhr,status,e) { console.dir(e); }); } $(document).ready(function() { newsDiv = document.querySelector("#newswell"); getData(); }); </script> </body> </html>
Я предполагаю, что приведенный выше код достаточно тривиален, чтобы не нуждаться в каких-либо объяснениях, но если я ошибаюсь, просто дайте мне знать в комментариях. Теперь давайте посмотрим на обновленную версию с использованием API.
<!DOCTYPE html> <html> <body> <div id="newswell"></div> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <script> var newsDiv; var active = true; function isVisible() { if("webkitHidden" in document) return !document.webkitHidden; if("mozHidden" in document) return !document.mozHidden; if("hidden" in document) return !document.hidden; //worse case, just return true return true; } function getData() { $.ajax({url:"news.json"}).done(function(data) { newsDiv.innerHTML += "<p><b>Posted at " + new Date() + "<br/>" + data.message; //call it again in 2 seconds if(isVisible()) window.setTimeout(getData, 2000); else active = false; }).fail(function(xhr,status,e) { console.dir(e); }); } $(document).ready(function() { newsDiv = document.querySelector("#newswell"); $(document).bind("visibilitychange webkitvisibilitychange mozvisibilitychange",function(e) { console.log("VS CHANGE"); console.log(isVisible()); if(isVisible() && !active) { active = true; getData(); } }); getData(); }); </script> </body> </html>
Давайте решать это по крупицам. Во-первых, обратите внимание на использование обработчика событий в блоке document.ready. События Page Visibility по-прежнему имеют префикс, поэтому я встроил поддержку для версий без префиксов, Chrome и Mozilla. (Помните, что IE поддерживает это, так что теоретически я мог бы добавить префикс IE также, если это необходимо. Мне бы очень хотелось, чтобы кто-нибудь мог проверить, есть ли у IE этот префикс или нет.)
Говоря о префиксах, я построил функцию isVisible, которая оборачивает чеки в свойство document.hidden. Это основной способ определить, видим ли наш документ.
Как насчет активной переменной? Поскольку мы имеем дело с вызовами AJAX и асинхронным дерьмом, у нас сложная ситуация. Мы можем или не можем, чтобы текущий вызов AJAX срабатывал при изменении видимости. Если мы перешли от скрытого к видимому, но у нас уже был AJAX-вызов, мы не хотим его запускать сейчас. Если у нас есть один активный, обработчик обратного вызова будет обрабатывать планирование следующего вызова. Таким образом мы гарантируем, что мы не удвоим наши AJAX-вызовы и не забудем начать процесс заново.
Обязательно проверьте спецификацию, на которую я ссылался выше. У них также есть интересное демо. Вместо того чтобы останавливать свои AJAX-вызовы, они просто замедляют их. Я вижу, как оба способа справляются с этим эффективно.
Вы можете продемонстрировать это здесь: http://raymondcamden.com/demos/2013/may/28/crap.html . Если вы хотите, вы также можете демо-версию предварительной версии страницы здесь: http://raymondcamden.com/demos/2013/may/28/pre_crap.html
Простите за имена файлов. Я не уверен, что я думал там.
У этого API есть только один реальный недостаток. Согласно спецификации, браузер должен сообщать как скрытый, когда свернут. В моем тестировании это не было правдой. На самом деле, он не будет отображаться как скрытый, если вы поместите другое приложение впереди. Он сообщил только скрытый, когда я переключился на другую вкладку. Опять же, я считаю, что это лучше, чем ничего, и дополнительный код (10 строк?) Достаточно тривиален, чтобы он стоил вашего времени. EDIT: FYI, Firefox делает обратите внимание, когда вы сворачиваете приложение. Путь, Firefox.
Позже сегодня (скорее всего, сегодня вечером у меня большая презентация), я собираюсь показать еще один пример этого с использованием Edge Animate .