Modernizr — это JavaScript-библиотека, которая узнаёт, что из HTML5 и CSS3 умеет браузер пользователя. Определяя возможности браузера, разработчик может сделать откат некоторых функций для старых версий браузеров. Создатели Modernizr называют такую проверку feature detection, и это гораздо эффективнее, чем просто определить браузер, его версию и ОС.

Я был премного удивлён факту отсутствия развёрнутой статьи об этой JS-библиотеке (анонс не в счёт). Статья составлена из перевода официальной документации проекта, переводов нескольких статей и собственных дополнений.

Первый шаг

Для начала нужно получить свежую версию библиотеки с её официального сайта: Modernizr Download Builder.
Укажи галочками те технологии, тесты которых собираешься проводить, затем создай свою персональную версию библиотеки кнопкой «Generate». Если проставить все галочки, получившегося кода хватит на пару экранов небольшого ноутбука – всего 15 КБ.
Затем просто подключи его к своей странице и проверь, как оно. Если всё работает, у элемента HTML должны появиться многочисленные классы:

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

Как можно легко догадаться: что добавлял галочками в библиотеку, те тесты и будут выполнены при подключении Modernizr, а потом добавлены классы в зависимости от браузера. Но не забудьте дать элементу HTML класс no-js, чтобы опираться на него, когда JS у клиента не включен.
Уже на этом этапе можно создавать очень эффективные таблицы стилей, например:

.multiplebgs selector {
	background-image: url('image.png') center 10px no-repeat, url('background.png');
}
.no-multiplebgs selector {
	background-image: url('image.png') center 10px no-repeat lightgray;
}

Думаю, фантазия опытного верстальщика подскажет примеры более красочные и развёрнутые.

Тесты

Проверка на присутствие той или иной технологии в браузере – тест.
На тесты, которые проводит Modernizr, можно цеплять события. Тест пройден — зацепка yep, не пройден — nope. Очень мило.

Modernizr.load({
  test: Modernizr.geolocation,
  yep : 'geo.js',
  nope: 'geo-polyfill.js'
});

yep – подключаю сценарий, использующий геолокационные возможности браузера.
nope – пытаюсь обойтись без них в geo-polyfill.js.

Говорят, что вот так тоже можно делать:

if (Modernizr.geolocation) {
// функции
}

А почему бы и нет?

Вот пример посложнее:

// Дай функции Modernizr.load строку, объект или массив строк и объектов
Modernizr.load([
  // Поли-заполнители для презентации
  {
    // Список того, что нам нужно
    test : Modernizr.fontface && Modernizr.canvas && Modernizr.cssgradients,
    // Modernizr.load загружает css и javascript
    nope : ['presentational-polyfill.js', 'presentational.css']
  },
  // Действенные поли-заполнители
  {
    // Авось прокатит
    test : Modernizr.websockets && window.JSON,
    // socket-io.js и json2.js
    nope : 'functional-polyfills.js',
    // А ещё можно дать массивы ресурсов для загрузки
    both : [ 'app.js', 'extra.js' ],
    complete : function () {
      // Запускаю это после того, как всё в этой группе было скачано
      // и запущено, вдобавок ко всем предыдущим группам
      myApp.init();
    }
  },
  // Запускаю анализ после всего, что нужно сделать.
  'post-analytics.js'
]);

Не так уж и сложно, верно?
и не придирайтесь к слову “поли-заполнитель” – MicroSoft отлично его перевели.

Одна из крутых возможностей Modernizr.load – возможность выстроить подключаемые сценарии в очередь. Многим это может ни о чём не говорить, но пользователи HTML5 Boilerplate скорее всего знакомы с запасным jQuery из Google CDN. Выглядит как-то так:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js"></script>
<script>window.jQuery || document.write('<script src="js/libs/jquery-1.7.1.min.js">\x3C/script>')</script>

Работает так: сначала пытается загрузить jQuery в сценарии, а затем – сразу же после, проверяя, что объект jQuery доступен. Если нет, то пытается загрузить локальную копию jQuery. Это не так-то уж и просто, и Modernizr.load спешит на помощь. Следуй вот такой логике, и он возьмёт в свои руки порядок подключения сценариев:

Modernizr.load([
  {
    load: '//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js',
    complete: function () {
      if ( !window.jQuery ) {
            Modernizr.load('js/libs/jquery-1.7.1.min.js');
      }
    }
  },
  {
    // Это будет ждать откат для загрузки и запуска, если это необходимо.
    load: 'needs-jQuery.js'
  }
]);

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

Расширяемость

Очень кстати разработчики Modernizr дали возможность расширять библиотеку самостоятельно с помощью Modernizr.addTest.
Простейший пример:

// Тест на поддержку элемента <track>
Modernizr.addTest('track', function(){
  var video = document.createElement('video');
  return typeof video.addTextTrack === 'function'
});

В документации есть раздел «Extensibility», посвящённый расширяемости, где всё подробно описано. А в проекте на GitHub’е есть папка, куда складывают все годные пользовательские расширения: /feature-detects/.

Поддержка браузеров

IE6+, Firefox 3.5+, Opera 9.6+, Safari 2+, Chrome. На мобильных устройствах – Mobile Safari на iOS, Webkit на Android’s, Opera Mobile, Firefox Mobile и есть большие надежды на поддержку Blackberry 6+.

Заключение

Отличное подспорье для проектов с плюс-минус широкой аудиторией, когда хорошая поддержка важнее времени загрузки и исполнения страницы. Впрочем, если знать меру – можно и на простые одностраничные сайты его вешать, просто для удобства или даже за делом.
Modernizr используют в довольно крупных компаниях: twitter, Google, Microsoft.

Ссылки

 

 

Источник: http://habrahabr.ru/post/144352/