Статьи

Регрессивное улучшение с помощью Modernizr и Yepnope

Версия 1.0 загрузчика сценариев yepnope.js Алекса Секстона была выпущена на прошлой неделе, поэтому я подумал, что было бы неплохо показать вам, как можно объединить Yepnope с Modernizr для использования функций HTML5 без дополнительных загрузок для пользователей с браузеры.

Что такое регрессивное улучшение?

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

Техника « polyfill » или «регрессивное улучшение» просто означает, что вы идете дальше и используете новые функции, а затем используете JavaScript для эмуляции собственного поведения в старых браузерах. Таким образом, вместо использования сценария для предоставления теней во всех браузерах, вы просто пишете свой CSS со свойством box-shadow , а затем включаете сценарий, который прозрачно принимает это свойство и использует указанные вами значения для создания тени в JavaScript.

Что такое Модернизр?

Для тех из вас, кто не знаком с этим, Modernizr — это небольшая (3,7 КБ в сжатом формате) библиотека JavaScript, которая обнаруживает наличие функций HTML5 и CSS3 в браузере. Раена воспользовалась этим в своем недавнем уроке по созданию прогрессивно улучшенной галереи изображений , а Кевин взял интервью у Пола Айриша , одного из создателей библиотеки, в недавнем эпизоде ​​покаста SitePoint.

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

Существует два основных способа использования Modernizr. Самый распространенный способ — использовать HTML-классы, которые он добавляет к вашему HTML-тегу. При просмотре страницы с помощью Modernizr в последней бета-версии Firefox 4, вот что я вижу в открывающем теге <html>:

 <html class=" js flexbox canvas canvastext webgl no-touch geolocation postmessage no-websqldatabase indexeddb hashchange history draganddrop no-websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity no-cssanimations csscolumns cssgradients no-cssreflections csstransforms no-csstransforms3d csstransitions fontface video audio localstorage no-sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths" lang="en"> 

Все эти классы говорят мне, какие функции доступны в браузере. Например, у меня есть @ font-face, веб-работники и CSS3 box-shadow, text-shadow и border-image, но у меня нет веб-сокетов или трехмерных CSS-преобразований. Итак, в моем CSS я могу сделать что-то вроде этого:

 .borderradius .box { -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; } .no-borderradius .box { // fallback code providing an alternate styling to browsers that don't support border-radius } 

Это достаточно просто. Круто то, что Modernizr также предоставляет вам JavaScript API, который может сообщить вам, доступна ли функция, включая несколько функций, которые не отображаются в классах тегов <html> . Например, допустим, у меня есть некоторый код JavaScript, который предоставляет значения заполнителей для элементов ввода. Мне не нужно запускать этот код, если браузер поддерживает атрибут placeholder, поэтому я могу использовать Modernizr для проверки этого перед выполнением моего фрагмента:

 if(!Modernizr.input.placeholder) { // custom placeholder code } 

Таким образом, мой код будет работать только в том случае, если нет встроенной поддержки браузера для текста-заполнителя.

Проблема

Здесь все еще есть небольшая проблема. Если браузер поддерживает атрибут placeholder, я все равно требую, чтобы он загружал кучу кода, который не делает ничего, кроме эмуляции поведения этого атрибута. Я уверен, что вы согласитесь, что это немного расточительно! Введите yepnope.js . Yepnope загружает скрипты, если выполняются определенные условия. Самое приятное то, что он прекрасно интегрируется с Modernizr, поэтому все становится на свои места.

Простейший пример с сайта библиотеки выглядит следующим образом:

 yepnope({ test : Modernizr.geolocation, yep : 'normal.js', nope : ['polyfill.js', 'wrapper.js'] }); 

Если браузер поддерживает геолокацию, этот фрагмент загрузит файл normal.js с сервера; в противном случае он загрузит как polyfill.js, так и wrapper.js.

Практический пример

Теперь, когда вы знаете, как работают все части, давайте соединим их в реальный пример. Допустим, у вас есть простая форма регистрации, состоящая из полей для имени пользователя, пароля и адреса электронной почты. Вот разметка:

 <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>yepnope.js test</title> <style> div { margin: 10px; } div p { font-size: 12px; color: #333; } </style> </head> <body> <form> <div> <label for="username">Username</label> <input type="text" required pattern="[a-z0-9_-]{3,15}" name="username" id="username"> <p>Between 3 and 15 characters. Only letters, numbers, underscores (_) and hyphens (-) are allowed.</p> </div> <div> <label for="email">Email</label> <input type="email" required placeholder="[email protected]" name="email" id="email"> </div> <div> <label for="password">Password</label> <input type="password" required name="password" id="password"> </div> <input type="submit" value="Submit"> </form> </body> </html> 

Форма использует ряд функций HTML5: обязательный атрибут, атрибут- placeholder и атрибут pattern . В поддерживаемом браузере, таком как бета-версия Firefox 4, он предоставляет текст-заполнитель и некоторую базовую проверку на стороне клиента:

Атрибут placeholder предоставляет текст местозаполнителя.

Тип ввода электронной почты обеспечивает встроенную проверку формата

Атрибут pattern обеспечивает проверку на основе регулярных выражений

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

Шаг 1: Загрузите Modernizr и Yepnope

Новый пользовательский конструктор Modernizr позволяет вам связывать yepnope прямо с Modernizr, так что давайте сделаем это. Зайдите на http://modernizr.github.com/Modernizr/2.0-beta/ . В этом случае все, что нам нужно обнаружить, — это атрибуты формы и типы ввода, поэтому установите эти два флажка, оставив флажки HTML5 Shim и Modernizr.load (yepnope.js).

Нажмите Generate, а затем Download Build, чтобы получить пользовательскую библиотеку Modernizr.

Шаг 2: Включите Modernizr в вашу страницу

Поскольку Modernizr необходимо определить, следует ли запускать другие сценарии, и добавить классы, которые могут потребоваться вашему CSS, он должен идти вверху HTML, а не внизу, как обычно рекомендуется:

 <script src="modernizr.custom.02401.js"></script> 

(Не забудьте заменить пользовательский номер сборки своим собственным.)

Шаг 3. Проверка поддержки функций

Теперь мы хотим проверить, поддерживает ли браузер новые типы ввода и атрибуты:

 yepnope({ test: Modernizr.inputtypes.email && Modernizr.input.required && Modernizr.input.placeholder && Modernizr.input.pattern, nope: 'h5f.min.js' }); 

Мы загружаем библиотеку H5F от Райана Седдона, которая эмулирует все новые типы ввода и атрибуты, которые мы используем в этом примере. В этом случае у нас есть один скрипт polyfill, который покрывает множество различных функций, поэтому мы проверяем их все сразу и загружаем полифилл, если хотя бы один из них не поддерживается. Это не всегда идеально, но мы делаем все просто для иллюстрации.

Вы также заметите, что мы не используем «yep» в этом вызове yepnope. Это нормально: если все функции, которые мы обнаруживаем, присутствуют, Yepnope ничего не сделает вообще, а мы этого хотим.

Шаг 4: Выполнить код обратного вызова

Возможно, у вас возникнет соблазн просто вызвать новую включенную библиотеку в следующей строке кода, но это не сработает. Yepnope.js загружает сценарии асинхронно , поэтому браузер не будет ждать окончания загрузки сценария, прежде чем перейти к следующей строке в вашем коде. Это означает, что если вы попытаетесь использовать функции, которые вы только что сказали Yepnope для загрузки, вы, скорее всего, получите ошибку.

Вместо этого, Yepnope позволяет вам установить функцию обратного вызова для каждого загружаемого вами скрипта, который будет запускаться после завершения загрузки этого скрипта. Вот как это работает:

 yepnope({ test: Modernizr.inputtypes.email && Modernizr.input.required && Modernizr.input.placeholder && Modernizr.input.pattern, nope: 'h5f.min.js', callback: function(url, result, key) { H5F.setup(document.getElementById("signup")); } }); 

Функция, указанная вами в качестве обратного вызова, будет вызываться при каждой загрузке скрипта. Это означает, что если вы указали и да, и нет, обратный вызов будет вызван дважды. К счастью, обратному вызову передаются три полезных параметра: url — это URL-адрес загруженного result , result — это логическое значение, представляющее, прошел ли ваш тест или нет, а key — это способ ссылки на конкретные ресурсы с использованием ключей (вы не не нужно беспокоиться об этом сейчас).

В приведенном выше примере я загружаю только скрипт на Nope. В результате, обратный вызов в любом случае будет вызываться только один раз, и только если тест не пройден, поэтому мне не нужно беспокоиться о параметрах.

Шаг 5: Готово!

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

Что дальше?

Я рассмотрел только самые простые случаи использования yepnope, js. Для такой крошечной библиотеки она обладает множеством функциональных возможностей, поэтому вам обязательно нужно прочитать страницу проекта, чтобы увидеть более продвинутые примеры использования. Даже если вы не используете его для полифилов HTML5 или CSS3, вы можете получить потенциальную выгоду от производительности при асинхронной загрузке ваших скриптов и по требованию, так что Yepnope все же стоит изучить.

Теперь все, что вам нужно сделать, это начать использовать новые функции HTML5 и CSS3 для использования на вашем веб-сайте, при этом вы уверены, что вы можете предоставить полнофункциональный запасной вариант для пользователей старых браузеров, не влияя на опыт более современных пользователей. дата посещения.