Хачим jquery.easyBox

Представляем EasyBox

Недавно нашёл неплохой lightbox-плагин для jQuery – EasyBox (https://code.google.com/p/easybox/)

Вот его описание и главные характеристики:
EasyBox это клон lightbox’а базирующийся на скрипте Slimbox2. Он предлагает множество различных дополнений и возможностей, как то:

  • отображение видео YouTube, Vimeo и DailyMotion
  • отображение строчного контента
  • отображение iframe’ов
  • улучшенная анимация
  • поддержка тем

И ещё:
Что делает EasyBox отличным?

  • распознает пропорции и разеры видео
  • отображает сообщения об ошибке если рисунок или ссылка недоступны
  • сжимает контент до размера страницы
  • сохраняет события JavaScript на строчных элементах
  • поддерживает управление колесиком мыши
  • поддерживает слайдшоу
  • поддерживает Drag & Drop

Неплохо, да?

Подключаем EasyBox к нашему проекту

Подключаем его так (самый простой вариант):

Скачиваем его отсюда например: http://easybox.googlecode.com/files/easybox-v1.4.zip
(если вы читаете это не в 2014-начале 2015 года, возможно, появится новая версия, можно пошариться на его родном сайте, хотя я не знаю что там можно ещё улучшить).

Распаковываем его в наш проект в отдельную папку (конечно, иерархию папок вы можете использовать абсолютно любую).

В head страницы добавляем ссылки на CSS с нужной темой:

<link rel="stylesheet" href="/easybox/styles/default/easybox.min.css" type="text/css" media="screen" />

В данном случае это тема default, но можно поиграться и с другими темами.

Подключим jquery, например так:

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>

А затем ссылки на сам easybox, либо так:

<!-- объединенный -->
<script type="text/javascript" src="/easybox/distrib.min.js"></script>

Или три ссылки:

<script type="text/javascript" src="/easybox/easybox.min.js"></script>
<script type="text/javascript" src="/easybox/handlers.min.js"></script>
<script type="text/javascript" src="/easybox/extras/autoload.min.js"></script>

Теперь, чтобы создать ссылку на лайтбокс, помечаем её классом lightbox, например так:

<a href="images/diplom.jpg" title="Красный диплом института искусств им. П. А. Серебрякова" class="lightbox">
  <img src="images/diplom_thumb.jpg" class="white shadow" alt="Диплом">
</a>

В данном случае на странице отображается небольшой рисунок диплома (images/diplom_thumb.jpg), а по щелчку на нем открывается лайтбокс с изображением увеличенного диплома (images/diplom.jpg).

Аналогично можно добавить ссылки на YouTube или iframe, так чтобы они открывались в лайтбоксе:

<a href="http://www.youtube.com/watch?v=VIDEO_ID" title="Video caption" class="lightbox">Моё видео на Ютубе!</a>
<a href="http://www.example.com" title="Example page" class="lightbox" data-width="320" data-height="240">Мой iframe в лайтбоксе!</a>

Вместо VIDEO_ID подставляем естественно ид видео на Ютубе. Для iframe мы также указали его размеры (это делать не обязательно).

Хачим EasyBox

Тут вы спросите резонно – но если этот самый EasyBox так крут, что там можно хачить?
А я так же резонно отвечу – хачить есть всегда что, идеальных продуктов наверное не бывает.

Несмотря на то, что в описании EasyBox‘а помимо всего прочего написано: EasyBox’ look is fully customizable, на самом деле это конечно не так.

Что нам нужно?

  1. Панель управления с описание и кнопкой закрытия (крестиком) вверху окна лайтбокса.
  2. Чтобы верхняя часть содержимого была на виду (если не помещается по вышине, то должна быть у границы верхнего viewport’а браузера, а не выезажть за её границу).

EasyBox раскрывает лайтбокс с содержимым, центрируя его по высоте и ширине, при необходимости его чуть ужимая – но большое содержимое всё равно может не влезть целиком в окно (viewport) браузера.

Панель управления (называется bottom) с подписью и кнопкой закрытия (а при необходимости кнопками управления слайдшоу) находится внизу окна, и никак его вверх опцией не поставишь.

Что делать?
Берём девелоперскую версию easybox.js (не minified) с github’а и работаем с ней.
Версия: Easybox v1.4

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

В пределах 70-ой строки находим такой код:

/*
	Initialization
*/
$(function() {
	$(doc.body).append(
		$([
			overlay = $('<div id="easyOverlay" />').click(userClose)[0],
			center = $('<div id="easyCenter" />').append([
				container = $('<div id="easyContainer" />')[0],
				loadingIndicator = $('<div id="easyLoadingIndicator" />')[0],
				bottom = $('<div id="easyBottom" />').append([
					navLinks = $('<div id="easyNavigation" />').append([
						prevLink = $('<a id="easyPrevLink" href="#" />').click(previous)[0],
						nextLink = $('<a id="easyNextLink" href="#" />').click(next)[0]
					])[0],
					closeLink = $('<a id="easyCloseLink" href="#" />').click(userClose)[0],
					slideLink = $('<a id="easySlideLink" href="#" />').click(toggleSlide)[0],
					caption = $('<div id="easyCaption" />')[0],
					number = $('<div id="easyNumber" />')[0]
				])[0]
			])[0]
		]).css("display", "none")
	);
});

Лайтбокс состоит из 2-х основных частей – overlay, необходимого для затеменения и перекрытия главного окна браузера, и center – центральная часть лайтбокса с содержимым и панелью управления.

Блок center в свою очередь содержит три части – container – контейнер для содержимого, loadingIndicator – индикатор загрузки, прячущайси в итоге под содержимым, и bottom – так у EasyBox неприхотливо названа панель управления. Само название bottom (с англ.: низ, дно) свидетельнствует о том, что автор изначально помещает его под содержимым.

А нам надо над. И мы берем строку с container, вырезаем её и переносим под bottom, убрав после него запятую (разделяющую элементы массива). А после bottom соотв. запятую убираем, иначе JavaScript парсер будет жестко ругаться.

В итоге получаем такой код:

	/*
		Initialization
	*/
	$(function() {
		$(doc.body).append(
			$([
				overlay = $('<div id="easyOverlay" />').click(userClose)[0],
				center = $('<div id="easyCenter" />').append([
					loadingIndicator = $('<div id="easyLoadingIndicator" />')[0],
					bottom = $('<div id="easyBottom" />').append([
						navLinks = $('<div id="easyNavigation" />').append([
							prevLink = $('<a id="easyPrevLink" href="#" />').click(previous)[0],
							nextLink = $('<a id="easyNextLink" href="#" />').click(next)[0]
						])[0],
						closeLink = $('<a id="easyCloseLink" href="#" />').click(userClose)[0],
						slideLink = $('<a id="easySlideLink" href="#" />').click(toggleSlide)[0],
						caption = $('<div id="easyCaption" />')[0],
						number = $('<div id="easyNumber" />')[0]
					])[0],
					container = $('<div id="easyContainer" />')[0]
				])[0]
			]).css("display", "none")
		);
	});

Красота! Один пункт задачи мы выполинили, переходим к следующему.

Парсим глазами скрипт easybox.js далее, ищем место где лайтбокс появляется на экране (EasyBox использует шикарную анимацию).

Мы помним, что основной блок лайтбокса называется center, поэтому ищем что-то связанное с ним (я просто искал по целому слову center).

Нам надо найти изменение CSS-свойства top – ведь мы хотим разместить лайтбокс вверху окна, если он не влезает во viewport, и поэтому нам нужна вертикальная координата.

Но не находим ничего похожего по смыслу. Зато наш взгляд упирается в функцию animateCenter (начало её на строке 260). Судя по всему, эта функция как раз отвечает за анимирование и позиционирование лайтбокса в окне браузера. Наш пристальный и жесткий взгляд упирается в эту строчку:

// resize center
if ((center.offsetHeight != size[1]) || (center.offsetWidth != size[0]))
  p = {height: size[1], marginTop: -size[1]/2, width: size[0], marginLeft: -size[0]/2};

Да, именно здесь происходит позиционирование лайтбокса. Оказывается, easyBox использует не CSS-свойство top, а CSS-свойство margin-top (или marginTop в JS, что то же самое).

Значение marginTop: -size[1]/2 помещает лайтбокс в центр окна по вертикали (size[1] – размер лайтбокса по высоте).
Именно его нам надо подобратьь таким образом, чтобы лайтбокс начинался от верха окна, если он слишком высок.

Начинаем экспериментрировать. Пишем здесь marginTop: 0 и тестируем появление лайтбокса. Ууупс, он появился с верхом по центру окна. Значит, нам надо задать значение, равное половине высоты окна со знаком минус (чтобы лайтбокс ушел вверх, а не вниз от центра). В jquery высота viewport’а браузера находится простым методом $(window).height().

Значит, мы задаем значение так: marginTop: -($( window ).height() / 2)

Сохраняем скрипт, тестируем страничку – все получилось, вроде это то, что нам нужно!

Задание готово, получаем гонорар и идём спать! 🙂 Или читать интересные книги.

Да, итоговая функция animateCenter станет выглядеть так:

	function animateCenter(size, opacity, duration) {
		centerSize = size.slice();
		var p = {};
 
		// resize center и
		// подгоняем его к верхней границе browser's viewport
		if ((center.offsetHeight != size[1]) || (center.offsetWidth != size[0]))
			p = {height: size[1], marginTop: -($( window ).height() / 2), width: size[0], marginLeft: -size[0]/2};
		if (opacity > -1)
			p.opacity = opacity;
		$(center).animate(p, duration, options.resizeEasing);
	}

До встречи, друзья, вкусного чёрного чая с имбирем в сахаре!