Адаптивный плагин лайтбокс Magnific Popup (для jQuery и Zepto.js).

Лайтбокс является одним из тех инструментальных средств, которые отлично работают на персональных компьютерах, но с которыми часто возникают проблемы при работе на небольших мобильных устройствах. На сегодняшний день довольно трудно найти плагин, обладающий достаточным уровнем гибкости и способный моментально отображать содержимое. По этой причине я создал Magnific Popup (всплывающее окно), лайтбокс плагин с открытым исходным кодом, ориентированный на производительность.

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

1.Скорость.

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

Прогрессивная загрузка изображений.

Большинство плагинов лайтбокс используют методику предварительной загрузки образа изображения перед его полноценным отображением. Это делается для того, чтобы выяснить, оригинальный размер изображения и отцентрировать его с помощью JavaScript. Поскольку Magnific Popup центрирование контента осуществляется с помощью CSS, мы можем не использовать предварительную загрузку и вместо этого сразу же воспользоваться прогрессивной загрузкой изображения. Таким образом, мы сможем показывать и обрабатывать изображение как только будут получены основные данные.

Вы еще больше можете ускорить процесс отображения благодаря использованию прогрессивной визуализации JPEG. Загрузка происходит не с постепенным открытием изображения сверху вниз, а от низкого качества к высокому. Благодаря этому пользователь может различать образ изображения уже на начальном этапе загрузки. Выбор типа визуализации (рендеринга) — это вопрос предпочтения.

Progressive image loading

Изменение размеров, основанное на возможностях CSS.

Использование CSS подхода делает этот лайтбокс чрезвычайно гибким. Вы можете указать размер в относительных единицах, таких как EMS (расширяемая память), изменить размер всплывающие окна информационных запросов, и динамически обновлять всплывающий контент, не беспокоясь о том, как будет произведено его центрирование. Старайтесь избегать или, по крайней мере, уменьшить количество свойств изменения размеров в окне события resize. В противном случае значительно уменьшается быстродействие, по сравнению с изменением размера только благодаря чистой CSS.

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

В соответствии с принципом прогрессивного развития, я решил полностью отказаться от функции вертикального центрирования в IE 7. Для осуществления вертикального центрирования требовалось использование медленных CSS expressions (выражений CSS), которые убивают производительность старых версий браузеров. В отличие от современных браузеров, разрешение монитора, на котором  в настоящее время работает IE 7 необычайно легко предугадать. К примеру, мы знаем, что пользователь будет работать на старом ПК, который обычно имеет разрешение где-то между 800 × 600 и 1280 × 1024 пикселями, так что, мы можем просто установить фиксированные поля сверху: .lightbox-image { margin-top: 10%; }. Кроме того, вместо открытия лайтбокс, вы можете просто отобразить ссылку на содержание сайта. В Magnific Popup, вы можете сделать это следующим образом:

$('.popup-link').magnificPopup(function() {
  disableOn: function() {
 // Detect IE 7 or lower with your preferred method
 // and return false if you want to trigger the default action
    return isIE7 ? false: true;}
});

Центрирование HTML блока.

Вот основные критерии:

  1. Размер блока неизвестен и может быть изменен в любой момент.
  2. Блоки должно быть отцентрированы по горизонтали и вертикали.
  3. Если высота всплывающего окна больше, чем окна просмотра, то в таком случае должна появиться полоса прокрутки, и контекстное меню должно автоматически выровняться.

Я нашел один надежный способ, который помогает вертикально отцентрировать элемент с неопределенной высотой. Данный метод предполагает использование вспомогательного, встроенного в блок, элемента с установкой vertical-align: middle и height: 100%. Крис Коуер написал превосходную статью, описывающую эту технику. Этот метод прекрасно работает и удовлетворяет всем трем требованиям.

Центрирование изображения с заголовком.

В дополнение к требованиям HTML блока, изображение должно также удовлетворять следующим требованиям:

  • Оно должно соответствовать области по горизонтали и вертикали.
  • Его максимальная высота должна равняться высоте оригинального изображения.
  • Заголовок должен быть расположен непосредственно под изображением, а текст может размещаться не более чем в две строки.

Вот структура лайтбокс изображения:

<div>
  <img src="image.jpg"/>
  <div>Caption</div>
</div>

Реализация для изображения и с поддержкой IE 8 и версий выше не составит трудностей. Проблема возникает, когда вы пытаетесь позиционировать элементы рядом с изображением (например, надписи или специальные значки).

Я не смог найти подходящего решения для таких макетов без использования JavaScript, поэтому я использовал метод, который применяется max-height к изображению. Можно проверить пример на CodePen и посмотреть, как он работает.

Центрирование и-фрейма.

И-фреймы в Magnific Popup могут изменять размер, используя популярный и эффективный метод, описанный Тьерри Кобленцом в статье “Создание правильных соотношений для видео” на Отдельном списке. Все, что вам нужно сделать для правильного  масштабирования высоты элемента в зависимости от его ширины, это поместить его в контейнер и установить процентное заполнение верхнего отступа:

.iframe-container {
  width: 100%; height: 0; 
  overflow: hidden;/* element ratio is 4:3 (3/4 * 100) */
  padding-top: 75%; 
}
.iframe-container iframe {
  position: absolute;
  width: 100%; height: 100%;
  top: 0;
  left: 0;}

Высота окна в iPhone.

Мобильный браузер Safari на iPhone и iPod содержит неприятную ошибку: высота окна всегда уменьшается на величину высоты панели навигации, независимо от того присутствует бар или нет. Из-за этого происходит неправильное центрирование всплывающих окон. При исследовании этой проблемы, я нашел два возможных способа ее исправления:

  1. Нужно просто добавить 60 пикселей к значению высоты окна. Это решение не сработает для полноэкранного режима IOS 6, и приносит определенные неудобства.
  2. Использование события window.innerHeight вместо document.documentElement.clientHeight, которое будет возвращать правильное значение, но только тогда, когда размеры окна не увеличены.

Но я также нашел третий путь исправления этой проблемы (подробнее об этом методе вы сможете узнать из моего ответа на Переполнение стека):

var getIphoneWindowHeight = function() {
// Get zoom level of mobile Safari
// Such zoom detection might not work correctly on other platforms
  // 
var zoomLevel = document.documentElement.clientWidth / window.innerWidth;
// window.innerHeight returns height of the visible area. 
  // We multiply it by zoom and get our real height.
  return window.innerHeight * zoomLevel;};

Если вы знаете лучшие способы позиционирования элементов, чем те, что предлагаются здесь, мы были бы очень благодарны услышать их.

Предварительная загрузка соседних изображений в галерее.

Предварительная загрузка изображений в галерее имеет важное значение и значительно увеличивает скорость работы браузера. Обычный современный браузер принимает около шести соединений на имя хоста, тогда как IE 7 принимает только два.

После того, как галерея лайтбокс будет открыта, должна начаться загрузка не одного изображения, а целой группы (число элементов в группе должно зависеть от размера изображений и о от предполагаемого способа перехода посетителя к следующему кадру— проверьте как все работает!). Не думайте об ожидании загрузки следующего изображения, даже если текущий образ будет полностью загружен; в противном случае, это приведет к значительному снижению скорости работы браузера.

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

Parallel loading

Сравнение временной линии в параллельной и последовательное загрузке.

Поддержка DPI дисплеев.

Система команд управления Magnific Popup по умолчанию состоит из чистого CSS кода, без каких-либо внешних ресурсов. Таким образом, может быть организовано управление не только простыми, но и сложными DPI (т.е. сетчатк) дисплеями. Но в этом разделе статьи я хочу поговорить об использовании изображений для дисплеев с высоким пиксельным разрешением.

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

При исследовании, я обнаружил, что изображение naturalWidth определяется после того, как браузер получит его размер. Так что мы просто убираем интервал, который проверяется, если определено значение naturalWidth изображения, после того, как мы его масштабировали с помощью max-width, что составляет image.naturalWidth / window.devicePixelRatio. Вот упрощенная версия того, как осуществляется загрузка изображения :

var interval,
        hasSize,
        onHasSize = function() {
               if(hasSize) return;
  // we ignore browsers that don't support naturalWidth
    var naturalWidth = img[0].naturalWidth;
  if(window.devicePixelRatio > 1 && naturalWidth > 0) {
img.css('max-width', naturalWidth / window.devicePixelRatio);
               }
               clearInterval(interval);
               hasSize = true;},
        onLoaded = function() {
               onHasSize();},
        onError = function() {
               onHasSize();},
        checkSize = function() {
               if(img[0].naturalWidth > 0) {
                       onHasSize();}
        },
        img = $('<img />')
               .on('load', onLoaded)
               .on('error', onError)
// hd-image.jpg is optimized for the current pixel density
               .attr('src', 'hd-image.jpg') 
               .appendTo(someContainer);
interval = setInterval(checkSize, 100);
checkSize();

Существует очень распространенное мнение о том, что изображение, оптимизированное для Retina Display, весит в два раза больше, чем нормальное, но это не всегда правда. Так как изображение будет уменьшено, JPEG качество может быть изменено без заметного визуального отличия. Из своего опыта могу сказать, что сохранение изображения для 2-кратного пиксельного соотношения с 25% качеством JPEG, позволит получить визуально привлекательный результат. Размер файла при этом увеличится всего в 1,4 раза по сравнению с регулярным. Даан Джобсис написал прекрасную статью, которая описывает этот метод.

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

Как избежать дополнительных HTTP-запросов от элементов управления.

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

  • Создание всех элементов управления только с помощью CSS  (как это делает по умолчанию Magnific Popup).
  • Включать контроль графики в основной спрайт CSS вашего сайта, или выполнять предварительную загрузку с CSS перед открытием всплывающих окон.
  • С помощью схемы управления URI (универсальный идентификатор ресурса) вы можете вставлять закодированные в base64 изображения прямо в CSS (поддерживается IE 8 и версиями выше).

2.Доступность.

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

Условный лайтбокс.

Этот относительно новый метод, представленный Брэдом Фростом, полностью отключает лайтбокс на устройствах с маленьким экраном. Этот метод позволяет адаптироваться под мобильное использование. Вот несколько примеров:

  • Можно открывать карты и видео, как отдельную страницу. Многие мобильные браузеры будут принимать такие ссылки и открывать в специальном приложении, которым намного легче пользоваться.
  • Просто откройте изображение на новой странице для более удобного масштабирования и прокрутки.
  • Открывайте длинные текстовые всплывающие окна на новой странице. В Magnific Popup, вы можете сделать это, добавив событие всплывающего окна внутри атрибута данных и создав связь со страницей мобильного устройства в href атрибуте. Например:
<a href="separate-mobile-friendly-page.html" data-mfp-src="popup-content.html">Open popup</a>

Это всплывающая инициализация (с возможностью отключения всплывающих окон и открытием ссылки, когда окно превышает значения в 500 пикселей):

$('.popup-link').magnificPopup(function() {
  disableOn: function() {
    // Detect here whether you want to  ... 

Если вы хотите прочитать полностью статью, посетите сайт наших спонсоров

Comments are closed.