Проверка технологий HTML5

Марк Пилгрим

Оригинал: http://diveintohtml5.info/detect.html

Перевод: Влад Мержевич

Когда ваш браузер отображает веб-страницу, он конструирует объектную модель документа (Document Object Model, DOM) — набор объектов, представленных HTML-элементами на странице. Каждый элемент — каждый <p>, каждый <div> и каждый <span> — показан в DOM самостоятельным объектом (есть также глобальные объекты, вроде window или element, но они слишком специфичны).

Ко всем DOM-объектам можно применить основные свойства, но некоторые объекты имеют больше свойств, чем другие. В браузерах, поддерживающих возможности HTML5, отдельные объекты обладают уникальными свойствами. Заглядывание в DOM подскажет вам, какие возможности поддерживаются.

Вот четыре основных техники для исследования поддерживаемых браузером технологий. Начиная с более простой и заканчивая комплексной техникой.

1. Проверка что определенные свойства доступны для глобальных объектов (таких как window или navigator).

Пример: тест на поддержку геолокации

2. Создаем элемент, затем проверяем, что свойства для этого элемента существуют.

Пример: тест на возможность рисования

3. Создаем элемент, затем проверяем, что некоторые методы доступны для этого элемента, затем вызываем этот метод и смотрим возвращаемое значение.

Пример: тест для проверки поддерживаемых форматов видео

4. Создаем элемент, устанавливаем для определенных его свойств значения, затем проверяем, возвращаются ли эти значения.

Пример: тест для проверки, какие типы тега <input> поддерживаются

Библиотека Modernizr

Открытое программное обеспечение Modernizr это JavaScript-библиотека, распространяемая по лицензии MIT, для проверки поддержки большинства возможностей HTML5 и CSS3. На момент написания книги последняя версия 1.6, убедитесь, что у вас свежая версия. Для использования включите следующую строку в ваш документ.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Погружение в HTML5</title>
<script src="modernizr.min.js"></script>
</head>
<body>
...
</body>
</html>

Modernizr запускается автоматически, так что не надо использовать никакой функции modernizr_init() для вызова библиотеки. При запуске создается глобальный объект Modernizr, который содержит булево значение для каждой технологии. К примеру, если браузер поддерживает тег <canvas>, то Modernizr.canvas вернет true. Если браузер не поддерживает эту возможность, то Modernizr.canvas вернет false.

if (Modernizr.canvas) {
// Можно что-нибудь рисовать!
} else {
// Увы, нет встроенной поддержки рисования
}

Рисование

HTML5 определяет тег <canvas> как «холст для растровой графики, который может использоваться для отображения диаграмм, компьютерных игр или вывода других изображений на лету». Сам холст представляет собой прямоугольник на странице, в котором с помощью JavaScript рисуется, что вы пожелаете. HTML5 определяет набор функций называемых «Canvas API» для рисования фигур, контуров, создания градиентов и трансформации.

Для проверки Canvas API используется техника №2. Если ваш браузер поддерживает рисование, в DOM будет элемент <canvas>, к которому применим метод getContext(). Если браузер не поддерживает рисование, для <canvas> будут работать только основные свойства, но никак не специфичные.

function supports_canvas() {
return !!document.createElement('canvas').getContext;
}

Эта функция создает фиктивный элемент <canvas>. Такой элемент не применяется к документу, его даже нельзя увидеть. Он только покоится в памяти, нигде и ничего не делает, подобно лодке в безмятежной реке.

return !!document.createElement('canvas').getContext;

Когда вы создаете фиктивный <canvas>, его можно проверить на наличие метода getContext(). Этот метод будет существовать, если браузер поддерживает рисование.

return !!document.createElement('canvas').getContext;

Наконец, приводим результат к булевому типу (true или false) с помощью приема двойного отрицания.

return !!document.createElement('canvas').getContext;

Эта функция определяет поддержку основных элементов Canvas API, включая фигуры, контуры, градиенты и текстуры. Она не определяет стороннюю библиотеку explorercanvas, которая используется в Internet Explorer.

Вместо написания своей функции вы можете использовать Modernizr для определения поддержки Canvas API.

if (Modernizr.canvas) {
// Можно что-нибудь рисовать!
} else {
// Увы, нет встроенной поддержки рисования
}

Рисование текста

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

Проверка на рисование текста основана на технике №2. Если ваш браузер поддерживает рисование, то для созданного элемента <canvas> будет доступен метод getContext().Если браузер не поддерживает рисование, для <canvas> будут работать только основные свойства, но никак не специфичные.

function supports_canvas_text() {
if (!supports_canvas()) { return false; }
var dummy_canvas = document.createElement('canvas');
var context = dummy_canvas.getContext('2d');
return typeof context.fillText == 'function';
}

Данный пример начинается с проверки на возможность рисования, используя функцию supports_canvas(), вы ее видели в предыдущем разделе. Если браузер не поддерживает Canvas API, значит, нет и рисования текста!

if (!supports_canvas()) { return false; }

Далее, вы создаете фиктивный элемент <canvas> и получаете его контекст. Это гарантированно работает, поскольку функция supports_canvas() уже проверила, что метод getContext() существует для всех объектов <canvas>.

var dummy_canvas = document.createElement('canvas');
var context = dummy_canvas.getContext('2d');

Наконец, вы проверяете, есть ли в контексте рисования функция fillText(). Если да, значит рисование текста доступно. Ура!

return typeof context.fillText == 'function';

Вместо написания своей функции вы можете использовать Modernizr для определения поддержки рисования текста.

if (Modernizr.canvas) {
// Можно что-нибудь рисовать!
} else {
// Увы, нет встроенной поддержки рисования
}

Видео

HTML5 определяет новый элемент, названный <video>, для вставки видео на вашу страницу без использования сторонних плагинов вроде Apple QuickTime® или Adobe Flash®.

Тег <video> настроен для использования без всяких определяемых скриптов. Вы можете указать несколько видеофайлов и браузеры, которые поддерживает HTML5-видео, выберут тот формат, с которым они работают.

Браузеры, которые не поддерживают HTML5-видео, полностью игнорируют тег <video>, но это можно использовать в своих интересах и указать браузеру проигрывать видео через сторонний плагин. Крок Кэмен назвал такое решение Видео для каждого!, в нем используется HTML5-видео, если оно доступно и обращение к QuickTime или Flash для старых браузеров. Это решение не использует JavaScript и работает фактически во всех браузерах включая мобильные.

Если вы хотите большего, чем бульканье видео и его вывод на веб-странице, необходимо использовать JavaScript. При проверке на поддержку видео используется техника №2. Если браузер поддерживает HTML5-видео, в DOM будет создан объект, ассоциированный с <video>, у которого есть метод canPlayType(). Если браузер видео не поддерживает, то для созданного в DOM объекта будут работать только типовые свойства, доступные для всех элементов. Вы можете проверить поддержку видео с помощью следующей функции.

function supports_video() {
return !!document.createElement('video').canPlayType;
}

Вместо написания своей функции вы можете использовать Modernizr для определения поддержки видео.

if (Modernizr.video) {
// Смотрим кино!
} else {
// Нет встроенной поддержки видео
}

Форматы видео

Форматы напоминают языки, на которых говорят и пишут люди. В России некоторые газеты могут выходить на английском языке, но если вы читаете только по-русски, вряд ли они будут для вас полезны. Для проигрывания видео браузер должен понимать тот «язык», на котором написано видео.

«Язык» видео называется кодеком — это алгоритм, который используется для кодирования видео в поток битов. По всему миру распространено больше дюжины всяких кодеков. Какой же из них выбрать? К сожалению, браузеры не могут договориться о едином кодеке для проигрывания видео. Тем не менее, их количество сократилось до двух. Один из них требует денежных отчислений (потому что основан на патенте), но работает в Safari и iPhone. Другой кодек свободный и работает в таких браузерах как Chrome и Firefox.

Для проверки на поддержку форматов видео используется техника №3. Если браузер поддерживает HTML5-видео, в DOM будет создан объект, ассоциированный с <video>, у которого есть метод canPlayType(). Этот метод говорит о том, что браузер поддерживает некоторые форматы.

Эта функция проверяет, что формат H.264 поддерживается.

function supports_h264_baseline_video() {
if (!supports_video()) { return false; }
var v = document.createElement("video");
return v.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
}

Функция начинается с проверки на поддержку HTML5-видео с помощью функции supports_video(), о ней шла речь в предыдущем разделе. Если браузер не поддерживает видео, значит, не поддерживает и форматы!

if (!supports_video()) { return false; }

Затем создается фиктивный элемент <video>, который не будет виден и вызывается метод canPlayType(). Этот метод гарантированно будет доступен, поскольку функция supports_video() это обеспечивает.

var v = document.createElement("video");

Видео формат в действительности это комбинация разных вещей. В технической терминологии вы спрашиваете браузер, может ли он проиграть видео H.264 со звуком AAC в контейнере MPEG-4.

return v.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');

Функция canPlayType() не возвращает значение true или false, при распознавании формата функция возвращает следующую строку:

"probably" — браузер уверен, что сможет воспроизвести этот формат;
"maybe" — браузер думает, что, скорее всего, сможет воспроизвести;
"" (пустая строка) — браузер не знает такого формата.

Вторая функция проверяет открытие формата видео через Firefox и других браузеров с открытым кодом.

function supports_ogg_theora_video() {
if (!supports_video()) { return false; }
var v = document.createElement("video");
return v.canPlayType('video/ogg; codecs="theora, vorbis"');
}

И наконец, WebM, новый открытый (и свободный от отчислений) видео-кодек, который включен в новые версии основных браузеров, таких как Chrome, Firefox и Opera. Вы можете использовать аналогичную технику для определения поддержки видео WebM.

function supports_webm_video() {
if (!supports_video()) { return false; }
var v = document.createElement("video");
return v.canPlayType('video/webm; codecs="vp8, vorbis"');
}

Вместо написания своей функции вы можете включить Modernizr (версии 1.5 и старше) для определения поддержки разных форматов видео.

if (Modernizr.video) {
// Да, можно смотреть видео! Но какое?
if (Modernizr.video.webm) {
// Попробуем WebM
} else if (Modernizr.video.ogg) {
// Попробуем Ogg Theora + Vorbis в контейнере Ogg
} else if (Modernizr.video.h264){
// Попробуем H.264 + AAC в контейнере MP4
}
}

Локальное хранилище

Хранилище HTML5 позволяет сайтам сохранять информацию на локальном компьютере и обращаться к ней позже. Идея напоминает кукисы, но хранилище предназначено для сохранения гораздо большего объема информации. Кукисы ограничены в размерах, и ваш браузер каждый раз посылает веб-серверу запрос новой страницы (если на это есть время и позволяет полоса пропускания). Хранилище HTML5 остается на вашем компьютере, и сайты могут обращаться к нему через JavaScript после загрузки веб-страницы.

Спроси профессора Маркапа

В. Локальное хранилище действительно является частью HTML5? Почему же оно выделено в отдельную спецификацию?

О. Краткий ответ да, локальное хранилище это часть HTML5. Развернутый ответ такой — локальное хранилище входит в спецификацию, но отделено от нее, потому что некоторые люди из Рабочей группы HTML5 пожаловались, что HTML5 стал слишком большим. Если это звучит, как разрезание пирога на большее количество кусочков для уменьшения общего числа калорий, что ж, добро пожаловать в дурацкий мир стандартов.

Для проверки поддержки хранилища HTML5 используется техника №1. Если браузер поддерживает эту технологию, то будет доступно свойство localStorage для объекта window. Если же браузер не поддерживает хранилище, то свойство localStorage вернет значение undefined. В старых версиях Firefox была ошибка, при которой возникало исключение, если кукисы были отключены. Так что вся проверка проходит с использованием конструкции try...catch.

function supports_local_storage() {
try {
return 'localStorage' in window && window['localStorage'] !== null;
} catch(e){
return false;
}
}

Вместо написания своей функции вы можете использовать Modernizr для определения поддержки локального хранилища.

if (Modernizr.localstorage) {
// Хранилище доступно!
} else {
// Увы, нет поддержки локального хранилища
}

JavaScript чувствителен к регистру, атрибут Modernizr должен писаться как localstorage (в нижнем регистре), при этом свойство DOM вызывается как window.localStorage (смешанный регистр).

Спроси профессора Маркапа

В. Как насчет безопасности моего хранилища HTML5? Кто-нибудь может его прочитать?

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

Фоновые вычисления

Фоновые вычисления обеспечивают стандартный способ запуска JavaScript в браузере в фоновом режиме. С помощью этой технологии вы можете порождать несколько «потоков», которые запускаются одновременно, раньше или позже. Эти «фоновые потоки» могут производить сложные математические расчеты, делать сетевые запросы или осуществлять доступ к локальному хранилищу, пока пользователь пролистывает документ, щелкает мышью или набирает текст.

Для проверки поддержки фоновых вычислений используется техника №1. Если ваш браузер поддерживает эту технологию, глобальному объекту window будет доступно свойство Worker. В противном случае свойство Worker будет недоступно.

function supports_web_workers() {
return !!window.Worker;
}

Вместо написания своей функции вы можете использовать Modernizr для определения поддержки фоновых вычислений.

if (Modernizr.webworkers) {
// window.Worker доступно!
} else {
// Нет встроенной поддержки фоновых вычислений
}

JavaScript чувствителен к регистру, атрибут Modernizr должен писаться как webworkers (в нижнем регистре), при этом свойство DOM вызывается как window.Worker (с заглавной буквой W).

Оффлайновые приложения

Читать статичные веб-страницы оффлайн довольно просто: подключаетесь к Интернету, загружаете веб-страницу, отключаетесь от Интернета, уезжаете в уединенное место и читаете страницы на досуге. Для сбережения времени можно пропустить шаг насчет уединенного места. Но как насчет веб-приложений подобных Gmail или Google Docs? Спасибо HTML5, теперь любой (а не только Google) может создать приложение, которое будет работать оффлайн.

Оффлайновое приложение начинается как онлайновое. Когда вы первый раз посещаете сайт, поддерживающий оффлайновую работу, веб-сервер сообщает браузеру, какие файлы и в каком порядке нужны для работы. Это могут быть любые файлы — HTML, JavaScript, изображения, даже видео. Как только браузер скачает все необходимые файлы, вы можете посещать сайт даже без подключения к Интернету. Ваш браузер будет уведомлен, что вы отключены от сети, и надо использовать скачанные ранее файлы. Когда вы в следующий раз войдете в сеть, любые сделанные вами изменения могут быть отосланы на веб-сервер.

Проверить поддержку оффлайновых приложений можно с использованием техники №1. Если ваш браузер поддерживает эту технологию, будет доступно свойство applicationCache для глобального объекта window. Если браузер не поддерживает оффлайновые приложения, свойство applicationCache будет не определено.

function supports_offline() {
return !!window.applicationCache;
}

Вместо написания своей функции вы можете использовать Modernizr для определения поддержки оффлайновых приложений.

if (Modernizr.applicationcache) {
// window.applicationCache доступно!
} else {
// Увы, без сети ничего не работает
}

Учтите, что JavaScript чувствителен к регистру. Атрибут Modernizr должен писаться как applicationcache (в нижнем регистре), при этом свойство DOM вызывается как window.applicationCache (смешанный регистр).

Геолокация

Геолокация это способ выяснить, где вы находитесь в мире, по усмотрению можно делиться этой информацией с доверенными людьми. Существует несколько способов определить ваше положение — по IP-адресу, подключению к беспроводной сети, сотовому телефону или через GPS оборудование которое вычисляет координаты (широту и долготу) через спутники в небе.

 

Спроси профессора Маркапа

В. Геолокация это часть HTML5? Почему мы говорим о ней?

О. Поддержка геолокации включена в браузеры для будущей работы с новыми возможностями HTML5. Строго говоря, геолокация была стандартизирована Рабочей группой по геолокации, которая отделена из Рабочей группы HTML5. Но я все равно в этой книге говорю о ней, потому что эта часть развития Веба происходит в данный момент.

Для проверки поддержки геолокации используется техника №1. Если браузер поддерживает геолокацию, будет доступно свойство geolocation для глобального объекта navigator. В противном случае свойство geolocation будет недоступно. Вот как проверить поддержку геолокации.

function supports_geolocation() {
return !!navigator.geolocation;
}

Вместо написания своей функции, можно использовать Modernizr.

if (Modernizr.geolocation) {
// Можно смотреть, где вы находитесь!
} else {
// Нет встроенной поддержки геолокации.
}

Если браузер не поддерживает исходно геолокацию, не стоит терять надежду. Плагин с открытым исходным кодом Gear от Google работает в Windows, Mac, Linux, Windows Mobile и Android. Он расширяет возможности старых браузеров, которые не поддерживают новомодные вещи, описанные в этом разделе. В частности, Gear поддерживает геолокацию. Это не то же самое, что navigator.geolocation, но выполняет те же задачи.

Поля ввода

Вы знаете все о формах, не так ли? Пишем <form>, вставляем несколько <input type="text">, может быть <input type="password"> и заканчиваем все кнопкой <input type="submit">.

Вы знаете только половину. HTML5 определяет свыше дюжины новых полей, которые вы можете использовать в своих формах.

  1. <input type="search"> для поиска
  2. <input type="number"> для ввода чисел
  3. <input type="range"> ползунок
  4. <input type="color"> для выбора цвета
  5. <input type="tel"> для телефонного номера
  6. <input type="url"> для веб-адресов
  7. <input type="email"> для почтовых адресов
  8. <input type="date"> для выбора календарной даты
  9. <input type="month"> для месяца
  10. <input type="week"> для недели
  11. <input type="time"> для времени
  12. <input type="datetime"> для указания даты и времени
  13. <input type="datetime-local"> для местной даты и времени

Проверка на поддержку полей ввода происходит с помощью техники №4. Вначале вы должны создать фиктивный элемент <input> в памяти. По умолчанию значением атрибута type для тега <input> выступает text. В дальнейшем это окажется важно.

var i = document.createElement("input");

Далее, меняем значение атрибута type для фиктивного элемента <input> на проверяемое.

i.setAttribute("type", "color");

Если браузер поддерживает указанное поле ввода, тогда свойство type вернет установленное значение. В противном случае браузер проигнорирует это значение и вернет text.

return i.type !== "text";

Вместо написания тринадцати отдельных функций для проверки, вы можете использовать Modernizr для определения поддержки новых полей. Библиотека Modernizr повторно использует один <input> для эффективного определения всех 13 типов. Затем строится хэш, с именем Modernizr.inputtypes содержащий 13 ключей со значениями атрибута type и 13 булевых значений (true, если поддерживается и false, если нет).

if (!Modernizr.inputtypes.date) {
// Нет встроенной поддержки для <input type="date">
}

Подсказывающий текст

Кроме новых типов, HTML5 включает несколько небольших правок для имеющихся форм. Одно из таких усовершенствований это подсказывающий текст для тега <input>. Такой текст показывается внутри поля, пока оно не будет очищено или не получит фокус. Когда вы щелкаете в поле, подсказывающий текст исчезает.

Для проверки подсказывающего текста применяется техника №2. Если ваш браузер поддерживает эту возможность, в DOM будет создан объект соответствующий <input>, у которого имеется свойство placeholder. В противном случае, это свойство для <input> будет недоступно.

function supports_input_placeholder() {
var i = document.createElement('input');
return 'placeholder' in i;
}

Вместо написания собственной функции, вы можете использовать Modernizr для проверки.

if (Modernizr.input.placeholder) {
// Подсказывающий текст будет виден!
} else {
// Нет поддержки подсказывающего текста,
// надо использовать скрипты
}

Автофокус форм

Веб-сайты могут использовать JavaScript для автоматического перемещения фокуса к первому элементу формы. К примеру, на главной странице сайта Google.ru включен автофокус для поля ввода поискового запроса, поэтому не приходится перемещать в него курсор. Это удобно для большинства людей, за исключением продвинутых пользователей. Если нажать пробел, произойдет прокрутка страницы, но не в случае использования автофокуса, поскольку фокус находится в текстовом поле. Вместо прокрутки в тексте будет набран пробел. Если фокус находится в другом текстовом поле, пока страница загружается, скрипт автофокуса может «услужливо» перенести фокус обратно к исходному полю, тем самым заставляя вас набирать текст в неверном месте.

Поскольку автофокус делается на JavaScript, могут возникнуть сложности при решении этих крайних случаев, и не так уж много решений для тех людей, которые не желают, чтобы их фокус «похищался».

Решением этих проблем является атрибут autofocus, который применяется ко всем элементам форм. Атрибут autofocus делает именно то, о чем и говорит его название: перемещает фокус к определенному полю. Поскольку для его работы используется разметка HTML, а не скрипт, то поведение будет одинаковым для всех сайтов. К тому же разработчики браузеров (или авторы расширений) могут предложить пользователям возможность отключать автофокус.

Проверка на поддержку автофокуса основана на технике №2. Если автофокусировку в формах, в DOM будет создан объект для представления <input>, у которого есть свойство autofocus. В противном случае это свойство не будет доступно. Вы можете проверить автофокус с помощью следующей функции.

function supports_input_autofocus() {
var i = document.createElement('input');
return 'autofocus' in i;
}

Вместо написания собственной функции, вы можете использовать Modernizr для проверки поддержки автофокуса.

if (Modernizr.input.autofocus) {
// Автофокус работает!
} else {
// Нет поддержки автофокуса,
// придется снова обращаться к скриптам
}

Микроданные

Микроданные это стандартный путь добавить дополнительную семантику на ваши веб-страницы. К примеру, вы можете использовать микроданные для сообщения, что фотография доступна под специальной лицензией. Также вы можете применять микроданные для разметки страницы «Обо мне». Браузеры, их расширения и поисковые системы конвертируют разметку микроданных в vCard — стандартный формат для обмена контактной информацией.

Стандарт микроданных HTML5 включает как разметку HTML (в первую очередь для поисковых систем), так и функции DOM (преимущественно для браузеров). Вашим веб-страницам не повредит, если вы добавите в них разметку микроданных. Это не более чем несколько атрибутов, и поисковики, которые не понимают формат микроданных, их проигнорируют. Но если нужно получить доступ или управлять микроданными через DOM, тогда нужно проверять поддерживает ли браузер соответствующий API.

Для проверки применяется техника №1. Если браузер поддерживает микроданные, тогда будет доступна функция getItems() для глобального объекта document. Если браузер не поддерживает микроданные, тогда эта функция будет недоступна.

function supports_microdata_api() {
return !!document.getItems;
}

Библиотека Modernizr не содержит средств для проверки микроданных, поэтому необходимо использовать функцию, как показано выше.

API истории

API истории HTML5 представляет собой стандартизированный способ манипулировать историей браузера с помощью скрипта. Часть этого API — навигация по истории — была доступна в предыдущих версиях HTML. Новая часть в HTML5 это способ добавления записей в историю браузера и реагирование на удаление этих записей из стека, когда пользователь нажимает кнопку браузера «Назад». Это означает, что URL может продолжать выполнять свою работу как уникальный идентификатор для текущего ресурса, даже в нагруженных скриптами приложениях, которые не всегда полностью обновляют страницу.

Для проверки применяется техника №1. Если браузер поддерживает API истории, тогда будет доступна функция pushState() для глобального объекта history. Если браузер не поддерживает API истории, тогда эта функция будет недоступна.

function supports_history_api() {
return !!(window.history && history.pushState);
}

Вместо написания собственной функции, вы можете использовать Modernizr.

if (Modernizr.history) {
// Управление историей работает!
} else {
// Нет поддержки истории,
// попробуйте другие решения вроде History.js
}

Что еще почитать

JavaScript-библиотеки

  • Modernizr для проверки HTML5
  • geo.js для использования геолокации

Другие статьи

HTML по теме

Не выкладывайте свой код напрямую в комментариях, он отображается некорректно. Воспользуйтесь сервисом cssdeck.com или jsfiddle.net, сохраните код и в комментариях дайте на него ссылку. Так и результат сразу увидят.