В HTML5 есть что взволновать. Благодаря новой разметке, возможностям CSS и API-интерфейсам JavaScript возможности веб-приложений растут как на дрожжах. Добавьте к этому постоянное единство среди поставщиков браузеров, и список интересных функций расширяется почти ежедневно. От ночных сборок до выпусков каналов разработчиков и регулярных предварительных обзоров платформ браузеры быстро меняются, и веб-разработчики повсюду отправляются в увлекательное путешествие.
Но, несмотря на то, что сообщества разработчиков и браузеров поднимают шумиху в HTML5 до предела, подавляющее большинство людей в Интернете не используют совершенно новые браузеры и версии, которыми мы являемся. Если вы веб-разработчик в крупном магазине разработки или на предприятии с большой базой пользователей, вы, вероятно, уже знаете это. Даже если вы работаете с небольшим магазином или стартапом, предоставляющим какую-либо услугу через Интернет, вы, вероятно, тратите много времени на то, чтобы ваш сайт обслуживал как можно больше браузеров и версий браузеров.
Учитывая эту реальность, это легко увидеть HTML5 не с точки зрения того , это он готов к использованию сегодня, но будет ли вы будете готовы к этому. Например, предположим, что вы создали страницу с некоторыми новыми семантическими тегами (например, <header> и <article>), добавили некоторые новые функции CSS (например, border-radius и box-shadow) и даже добавили < элемент canvas> для рисования логотипа HTML5 на вашей странице.
В более новых браузерах, таких как Internet Explorer 9, Firefox 4 и более поздние версии или Google Chrome, это будет отображаться так, как показано на рисунке 1 . Но если вы попытаетесь загрузить эту страницу в Internet Explorer 8 или более ранней версии, вы увидите нечто похожее на рисунок 2 : совершенно испорченная страница.
Рисунок 1. Семантическая страница со стилями и элементом HTML5 <canvas>, отображаемая в Internet Explorer 9
Рис. 2. Та же самая семантическая страница, отображаемая в Internet Explorer 8 без стилей и без <canvas>
Я бы не стал винить вас, если бы вы посмотрели на все замечательные возможности HTML5 и, испытав подобное, сказали себе, что лучше всего подождать. Легко прийти к выводу, что HTML5 не готов ни для вас, ни для ваших пользователей.
Прежде чем вы решите установить дату в 2022 году, чтобы еще раз взглянуть на HTML5, я прошу вас прочитать оставшуюся часть этой статьи. Моя цель в этом месяце — дать вам практические стратегии для того, как вы можете использовать технологии HTML5 сегодня, не приводя к постепенной деградации, показанной на рисунке 2 . В этой статье я расскажу:
- Обнаружение функций в сравнении с анализом пользовательских агентов (UA)
- Полифиллинг с помощью JavaScript
- Изящная деградация
Эти три предмета должны рассказать вам многое из того, что вам нужно знать для создания веб-сайтов для широкого спектра браузеров. К тому времени, когда мы закончим, у вас будет надежная стратегия для уверенного и безотлагательного внедрения технологий HTML5. У вас также будут некоторые инструменты, которые вы можете использовать для постепенного улучшения сайтов для новых браузеров, а также для других.
Важность обнаружения функций
Чтобы обеспечить стабильную и согласованную работу браузеров, разработчикам часто требуется некоторая информация о браузере пользователя. Исторически сложилось так, что эту информацию с помощью JavaScript определяли так:
var userAgent = navigator.userAgent; if (userAgent.indexOf('MSIE') >= 0) { console.log("Hello, IE user"); } else if (userAgent.indexOf('Firefox') >= 0) { console.log("Hello, Firefox user"); } else if (userAgent.indexOf('Chrome') >= 0) { console.log("Hello, Chrome user"); }
Этот метод, известный как UA sniffing, широко используется для определения, какой браузер запрашивает вашу страницу. Логика заключается в том, что, зная браузер пользователя (например, Internet Explorer 7), вы можете принимать во время выполнения решения о том, какие функции вашего сайта включить или отключить. UA sniffing равносильно тому, чтобы сказать браузеру: «Кто ты?» (Для углубленного анализа UA сниффинга и других методов обнаружения см. Bit.ly/mlgHHY .)
Проблема с этим подходом состоит в том, что браузеры могут быть обмануты. Строка UA — это настраиваемая пользователем часть информации, которая на самом деле не обеспечивает 100-процентную точную картину рассматриваемого браузера. Более того, поскольку этот метод получил широкое распространение, многие поставщики браузеров добавили дополнительный контент в свои собственные строки UA, чтобы обманным путем вывести сценарии на неверные предположения о том, какой браузер использовался, и таким образом обойти обнаружение. Некоторые браузеры теперь даже включают функцию, которая позволяет пользователям изменять свою строку UA всего несколькими щелчками мыши.
Однако цель UA sniffing — никогда не знать браузер и версию пользователя. И, конечно же, это не было целью дать вам возможность сказать своим пользователям «скачать другой браузер», если они использовали тот, который вам не понравился, даже если этот метод используется некоторыми. У пользователей есть выбор в том, какой браузер они используют, но наша ответственность как разработчиков заключается в том, чтобы предоставить максимально надежный и последовательный опыт, а не навязывать им мнение о предпочтении браузера. Цель UA sniffing всегда состояла в том, чтобы дать вам точную картину возможностей или функций, которые вы могли бы использовать в текущем браузере пользователя. Знание самого браузера является лишь средством получения этой информации.
Сегодня есть альтернативы нюханию UA, и популярность растет, отчасти благодаря jQuery и Modernizr, и называется обнаружением объектов или объектов. Эти термины в основном взаимозаменяемы, но в этой статье я остановлюсь на «обнаружении возможностей».
Цель обнаружения функции — определить, поддерживается ли данная функция или функция в текущем браузере пользователя. Если UA sniffing — это все равно, что спрашивать браузер «кто ты», то обнаружение функций — это все равно, что спрашивать браузер «на что ты способен» — гораздо более прямой вопрос и более надежный способ предоставить пользователям условную функциональность. Пользователям и браузерам гораздо сложнее подделать или ошибочно сообщить о поддержке функций, при условии, что сценарии обнаружения функций реализованы правильно.
Обнаружение функции вручную
Так как же выглядит обнаружение объектов в отличие от примера прослушивания UA? Чтобы ответить на этот вопрос, давайте рассмотрим исправление проблем, возникших при просмотре моей страницы HTML5, изображенной на рисунке 1 , в Internet Explorer 8 вместо Internet Explorer 9. Разметка для этой страницы приведена на рисунке 3 .
Рисунок 3 Страница с новой семантической разметкой HTML5
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>My Awesome Site</title> <style> body { font-size: 16px; font-family: arial,helvetica,clean,sans-serif; } header h1 { font-size: 36px; margin-bottom: 25px; } article { background: lightblue; margin-bottom: 10px; padding: 5px; border-radius: 10px; box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.5); } article h1 { font-size: 12px; } </style> </head> <body> <header><h1>My Awesome Site</h1></header> <article> <header><h1>An Article</h1></header> <p>Isn't this awesome?</p> </article> <canvas width="250" height="500"></canvas> </body> <script src="../js/html5CanvasLogo.js" type="text/javascript"></script> </html>
Различия между Internet Explorer 9 и Internet Explorer 8, как показано на рисунках 1 и 2 , являются существенными. Начнем с того, что моя страница полностью не стилизована, как будто CSS для этой страницы не существует. Более того, мне не хватает причудливого щита HTML5 внизу страницы. Каждая из этих проблем может быть легко устранена, и обнаружение функций является первым шагом к выявлению проблемы.
Причина обеих проблем проста: <header>, <article> и <canvas> не являются допустимыми элементами HTML для Internet Explorer 8, и поэтому я не могу с ними работать. Чтобы решить проблему <canvas>, вместо использования UA sniffing для определения того, какой браузер / версия используется, я хотел бы спросить браузер через JavaScript, поддерживается ли элемент <canvas> и его API-интерфейсы JavaScript. Моя функция проверки холста выглядит следующим образом:
!!document.createElement('canvas').getContext
Это утверждение делает пару вещей. Во-первых, он использует двойное отрицание (!!), чтобы неопределенные значения были явно ложными. Затем он вручную создает новый элемент canvas и присоединяет его к DOM. Наконец, он вызывает getContext, новую функцию, доступную для элементов <canvas>, для манипулирования Canvas API через JavaScript. Если я использую Internet Explorer 9, это утверждение вернет true. Если я использую Internet Explorer 8, getContext вернет «undefined», что при двойном отрицании приведет к значению false.
Это обнаружение функций в самом основном. Благодаря этому заявлению и другим подобным мне теперь у меня есть более надежный способ запроса поддержки функций в браузере. Для получения дополнительной информации об обнаружении функций вручную посетите страницу diveintohtml5.info/everything.html .
Использование Modernizr для обнаружения функций
Ручное обнаружение функции, безусловно, является улучшением при прослушивании UA, но этот подход все еще оставляет вас за тяжелую работу, как для определения доступности функции, так и для решения, что делать, если эта функция не существует. И хотя пример canvas был простым, требующим одну строку кода, это относится не ко всем функциям, которые вы можете захотеть обнаружить, равно как и код обнаружения не одинаков во всех браузерах. Обнаружение поддержки модулей CSS3, которые я использовал ранее (например, border-radius и box-shadow), может быть немного сложнее.
К счастью, Modernizr ( modernizr.com ) предлагает лучший подход. Modernizr — это библиотека JavaScript, которая «… обнаруживает доступность собственных реализаций для веб-технологий следующего поколения, то есть функций, основанных на спецификациях HTML5 и CSS3». Добавление ссылки на Modernizr на ваших страницах предоставляет четыре основных функции:
- Полный список поддерживаемых функций, который хитро добавлен в вашу разметку, что позволяет использовать условные определения CSS.
- Объект JavaScript, который помогает в обнаружении функций на основе сценариев.
- Все новые теги HTML5 добавлены в DOM во время выполнения для удобства Internet Explorer 8 и предыдущих браузеров Internet Explorer (подробнее об этом чуть позже).
- Загрузчик скриптов для условной загрузки полифиля на ваши страницы.
Мы не будем больше обсуждать первый пункт в этой статье, хотя я призываю вас перейти на modernizr.com и ознакомиться с документацией по этой и остальным функциям.
Второй элемент — это функция, которая помогает перевернуть эту строку кода:
!!document.createElement('canvas').getContext
В эту строку кода:
Modernizr.canvas
Это возвращает логическое значение, указывающее, поддерживается ли элемент canvas на странице. Преимущество использования Modernizr в отличие от развертывания собственного обнаружения функций заключается в том, что Modernizr — это хорошо протестированная, надежная и широко используемая библиотека, которая делает тяжелую работу за вас. Twitter, Google, Microsoft и многие другие используют Modernizr, и вы тоже можете. Благодаря обновлению ASP.NET MVC 3 Tools (выпущенному в апреле 2011 года) Microsoft даже поставляет Modernizr в комплекте с новыми приложениями ASP.NET MVC. Конечно, все, чего я достиг на этом этапе, это обнаружил, поддерживается ли элемент <canvas>. Я ничего не сказал о том, что делать дальше. Учитывая, что с помощью обнаружения функций, что функция является или не доступна для браузера,следующим общим шагом является создание некоторой условной логики, которая препятствует выполнению определенного кода, если функция не существует, или выполняет альтернативный путь, подобный этому:
if (Modernizr.canvas) { // Execute canvas code here. }
Добавление функций на ваш сайт, основанное на наличии дополнительных возможностей браузера, называется «прогрессивным улучшением», потому что вы расширяете возможности для более функционального браузера. На другом конце спектра находится «постепенная деградация», когда отсутствие определенных функций не приводит к ошибкам или сбоям в работе браузера, а скорее предоставляет пользователю некоторую ослабленную функцию или альтернативную возможность. Для более старых браузеров постепенная деградация не должна быть вашей опцией по умолчанию. Во многих случаях это может даже не быть вашим лучшим вариантом. Вместо этого, с помощью Modernizr, вы часто можете использовать одну из многих доступных политик заполнения браузера, чтобы добавить HTML5-подобные функции в не поддерживающие браузеры.
Что такое полифилы?
Согласно веб-сайту Modernizr, полизаполнение — это «оболочка JavaScript, которая копирует стандартный API для старых браузеров». «Стандартный API» относится к данной технологии или функции HTML5, например, canvas. «JavaScript shim» подразумевает, что вы можете динамически загружать код JavaScript или библиотеки, имитирующие эти API, в браузерах, которые их не поддерживают. Например, полифил Geolocation добавит глобальный объект геолокации к объекту навигатора, а также добавит функцию getCurrentPosition и объект обратного вызова «шнуры», как это определено в API геолокации World Wide Web Consortium (W3C). Поскольку полифилл имитирует стандартный API, вы можете разработать этот API на перспективу для всех браузеров с целью удаления полифилла, когда поддержка достигнет критической массы. Никакой дополнительной работы не требуется.
Добавив ссылку на Modernizr на моей странице, я сразу же получу одно преимущество в области полифиллинга, связанное с примером на рисунке 3 . Страница отображается без стиля, потому что Internet Explorer 8 не распознает такие теги, как <article> и <header>. И поскольку он не распознал их, он не добавил их в DOM, как CSS выбирает элементы для стилизации.
Когда я добавляю тег <script> и ссылку на Modernizr на мою страницу, в результате получается стилизованная страница, как на рисунке 4 . Я получаю это преимущество, потому что Modernizr вручную добавляет все новые теги HTML5 в DOM с помощью JavaScript (document.CreateElement (‘nav’)), который позволяет выбирать и стилизовать теги с помощью CSS.
Рисунок 4. Страница HTML5 в Internet Explorer 8 с помощью Modernizr
Помимо использования для добавления поддержки новых элементов HTML5 в Internet Explorer, библиотека Modernizr не предоставляет никаких дополнительных полифилов из коробки. Те, которые вы предоставляете сами, либо из ваших собственных скриптов, либо из постоянно растущего списка опций, документированных на веб-сайте Modernizr. Начиная с версии 2.0 Modernizr предоставляет загрузчик условных сценариев (на основе yepnope.js — yepnopejs.com ), который помогает асинхронно загружать библиотеки полизаполнения только при необходимости. Использование Modernizr с одной или несколькими библиотеками полизаполнения, которые предоставляют необходимые функции, является мощной комбинацией.
Использование Polyfills для симуляции функциональности HTML5
В случае canvas вы можете поддерживать полифилл для Internet Explorer 8 и более ранних версий с помощью Modernizr и библиотеки JavaScript под названием excanvas, которая добавляет поддержку холста на уровне API в Internet Explorer 6, Internet Explorer 7 и Internet Explorer 8. Вы можете загрузить excanvas из bit.ly/bSgyNR и, после добавления его в папку сценариев, добавить код в блок сценариев на своей странице, как показано на рисунке 5 .
Рисунок 5. Использование Modernizr для поддержки Polyfill Canvas
Modernizr.load({ test: Modernizr.canvas, nope: '../js/excanvas.js', complete: function () { Modernizr.load('../js/html5CanvasLogo.js'); } }]);
Здесь я использую загрузчик скриптов Modernizr, чтобы указать три вещи:
- Булево выражение для проверки
- Путь к скрипту для загрузки, если выражение оценивается как ложное
- Обратный вызов для запуска после завершения проверки или загрузки скрипта
В контексте canvas это все, что мне нужно, чтобы добавить немного интеллекта и полифиллинга в мое приложение. Modernizr будет асинхронно загружать excanvas.js только для браузеров, которые не поддерживают canvas, а затем загружает мою библиотеку сценариев для рисования логотипа HTML5 на странице.
Давайте посмотрим на другой пример, чтобы подчеркнуть значение Modernizr. Ориентированные на детали среди вас, возможно, заметили, что сайт, стилизованный на рисунке 4 , не совсем то же самое, что и исходная страница, представленная в Internet Explorer 9 и изображенная на рисунке 1 . На странице, как видно в Internet Explorer 8, отсутствуют тени и скругленные углы, и я не смог бы отправить этот замечательный сайт без них, поэтому мы снова обратимся к Modernizr за помощью.
Как и в случае с canvas, Modernizr может сказать мне, что модули CSS3 не поддерживаются, но я должен предоставить библиотеку для их заполнения. К счастью, есть библиотека под названием PIE ( css3pie.com ), которая предоставляет оба модуля в одной библиотеке.
Чтобы добавить поддержку border-radius и box-shadow, я могу добавить код на рис. 6 в мой скрипт после того, как я скачал PIE. На этот раз, я буду тест , чтобы увидеть , если либо граница радиуса или коробчатого теневые модули поддерживаются (в противоположность допущению , как всегда поддерживается или нет) , и если либо не поддерживается, динамически загружать PIE.js. После завершения загрузки PIE я выполню фрагмент jQuery, чтобы выбрать все мои теги <article>, и вызову функцию PIE.attach, которая добавляет поддержку стилей border-radius и box-shadow, уже определенных в моем CSS. Конечный результат изображен на рисунке 7 .
Рисунок 6. Использование Modernizr и PIE для добавления поддержки CSS3
Modernizr.load({ test: Modernizr.borderradius || Modernizr.boxshadow, nope: '../js/PIE.js', callback: function () { $('article').each(function () { PIE.attach(this); }); } });
Рисунок 7 Поддержка CSS3 с Modernizr и PIE
Использование Polyfills для помощи в постепенной деградации
В дополнение к использованию методов полизаполнения, обсуждаемых здесь, вы также можете использовать Modernizr для помощи в случаях, когда вы хотите изящно ухудшить качество своего приложения, в отличие от полизаполнения в другой библиотеке.
Допустим, у меня есть элемент управления Bing Maps на веб-странице, и я хочу использовать геолокацию, о которой мы подробно расскажем в следующей статье, чтобы найти текущее местоположение пользователя, а затем поместить это местоположение в качестве кнопки на элементе управления карты. ,
Хотя геолокация поддерживается в последних версиях всех браузеров, она не поддерживается в старых браузерах. Также немного сложнее обеспечить полную поддержку API Geolocation исключительно через JavaScript, и хотя полифилы для Geolocation действительно существуют, я решил вместо этого изящно ухудшить качество своего приложения. В тех случаях, когда браузер пользователя не поддерживает геолокацию, я предоставлю форму, которую она может использовать для ввода местоположения вручную, и затем я буду использовать ее для позиционирования и закрепления карты.
В Modernizr это простой вызов загрузки одного из двух созданных мною сценариев, как показано на рисунке 8 . В этом случае я тестирую свойство Modernizr.geolocation. Если true («yep»), я загружу свой скрипт fullGeolocation.js, который будет использовать API геолокации, чтобы найти мое местоположение (с моего разрешения) и поместить его на карту, как показано на рисунке 9 . Если, с другой стороны, тест ложен («нет»), я загружу резервный скрипт, который отображает форму адреса на моей странице. Когда пользователь отправит форму, я буду использовать предоставленный адрес для центрирования и закрепления карты, как показано на рисунке 10 . Таким образом, моя страница предоставляет отличный опыт для современных браузеров, но при этом изящно превращается в разумную альтернативу для старых.
Рис. 8. Использование Modernizr для обеспечения постепенной деградации
Modernizr.load({ test: Modernizr.geolocation, yep: '../js/fullGeolocation.js', nope: '../js/geolocationFallback.js' });
Рис. 9. Отображение с помощью геолокации
Рисунок 10. Предоставление поддержки резервирования геолокации
Легко взглянуть на некоторые из расширенных функций HTML5 и, учитывая большую пользовательскую базу в старых браузерах, решить, что ваш сайт не совсем к ним готов. Но уже есть отличные решения, которые не только помогают в изящной деградации, но также предоставляют возможность перенести эти старые браузеры в настоящее, чтобы ваши пользователи могли сейчас работать с HTML5. В ходе этой статьи вы увидели, что с помощью функции обнаружения, Modernizr и полифиллинга можно без задержек принять HTML5 для постоянно растущего сегмента ваших пользователей с помощью современного браузера, при этом стараясь не покидать остальная часть вашей пользовательской базы позади.