Lightbox от falbar или falbox

20 октября 2015 Антон Кулешов 1190 0

Совсем недавно, занимаясь внутренним обновлением сайта, я заметил, что в некоторых статьях есть картинки большей ширины, чем сам блок с контентом. Конечно, визуальному восприятию это не мешало, тем более что, я заранее старался подгонять картинки так, чтобы текст на них оставался читаемым. Однако, заглядывая в будущее, я решил, что возможность увеличения изображения для детального его рассмотрения будет весьма кстати даже на моём скромном сайте. Поэтому я написал функциональный lightbox с элементами слайдера и галереи, которым и решил поделиться в этой статье.

Реклама

По моей задумке код должен был решать несколько задач:

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

Это список относиться к функционалу скрипта, но хочется добавить пару пунктов относящийся к самой реализации:

  • Во-первых, HTML lightbox будет добавляться после загрузки страницы через JavaScript;
  • Во-вторых, при добавлении HTML учитывается наличие картинок: если их нет на странице – lightbox добавлен не будет, а если у нас на странице всего одно изображение, то будут отключены кнопки пролистывания;
  • В-третьих, не забываем про адаптивность и кнопки на клавиатуре, на которые пользователь может нажать при просмотре.

Описание скрипта будет относительно примера, который я прикрепил к статье. Для работы нам потребуется подключить только jQuery библиотеку:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>

Все картинки в примере лежат в элементе с id=content вперемежку с текстом. К ним мы не будем нечего прописывать и изменять их CSS. Все делаем через JavaScript – это гораздо удобнее, так как не требует дополнительных манипуляций со страницей.

Немного слов о структуре (непосредственно её рассмотрим при написании JavaScript): наш lightbox будет включать в себя несколько кнопок и обёртку для вывода изображения. Теперь для работы мы опишем CSS, который и будет отвечать за отображение:

#gallery{
	background-color: rgba(24, 59, 95, 0.3);
	overflow: auto;
	position: fixed;
	left: 0;
	top: 0;
	height: 100%;
	width: 100%;
	-webkit-user-select: none;
	-moz-user-select: none;
	-o-user-select: none;
	-ms-user-select: none;
	user-select: none;
	display: none;
	z-index: 1000;
}
	#gallery .prev{
		background-color: rgba(24, 59, 95, 0.7);
		position: fixed;
		left: 0;
		top: 0;
		height: 100%;
		width: 83px;
		opacity: 0.7;
		cursor: pointer;
		z-index: 1;
	}
		#gallery .prev .icon{
			display: block;
			background: url(icons-gallery.png) no-repeat 1px center;
			margin: 18px auto 0;
			width: 14px;
			height: 24px;
		}
	#gallery .prev:hover{
		opacity: 1;
	}
	#gallery .viewer{
		display: -webkit-flex;
		display: -moz-flex;
		display: -o-flex;
		display: -ms-flex;
		display: flex;
		align-items: center;
		height: 100%;
	}
		#gallery .viewer .image{
			overflow: hidden;
			margin: auto;
		}
		#gallery .viewer.next .image{
			position: relative;
			cursor: pointer;
		}
			#gallery .viewer .image img{
				max-width: 100%;
			}
	#gallery .close{
		position: fixed;
		right: 27px;
		top: 20px;
		opacity: 0.7;
		cursor: pointer;
		z-index: 1;
	}
		#gallery .close .icon{
			display: block;
			background: url(icons-gallery.png) no-repeat -31px center;
			width: 20px;
			height: 20px;
		}
	#gallery .close:hover{
		opacity: 1;
	}
	#gallery .zoom{
		background-color: rgba(24, 59, 95, 0.7);
		position: fixed;
		bottom: 10px;
		right: 27px;
		height: 20px;
		width: 20px;
		border-radius: 2px;
		padding: 10px;
		opacity: 0.7;
		cursor: pointer;
		z-index: 1;
	}
		#gallery .zoom .icon{
			display: block;
			background: url(icons-gallery.png) no-repeat -11px 2px;
			width: 22px;
			height: 20px;
		}
	#gallery .zoom:hover{
		opacity: 1;
	}

Вышеописанный код говорит о том, что изначально lightbox будет спрятан, а в элементе с id=gallery находятся все кнопки управления (пролистывание, закрытия и открытия изображения на новой вкладке) и элемент, в котором будет отображаться выбранная картинка пользователем. Так же важно отметить, что как фон, так и кнопки зафиксированы на странице – это нужно для того чтобы при появлении скролла кнопки оставались на том же месте, а скролл происходил не по странице, а по картинке (это реализуется при помощи обрезки элемента body и компенсации правого отступа).

Переходим собственно к JavaScript. Его мы поместим в объект gallery, а весь функционал будет реализован через методы. Главный метод, а также точкой запуска/входа является initialize(containerTmp, containerImg):

  • containerTmp – контейнер, куда будет помещаться HTML разметка lightbox;
  • containerImg – контейнер, в котором находятся картинки, к которым будет применен скрипт.

Далее следует весь код gallery:

var gallery = {

	IMGS: {},

	GALLERY: {},
	BODY: 	 {},

	CURRENT: 0,

	initialize: function(containerTmp, containerImg){

		this.IMGS = containerImg.find("img");

		if(this.IMGS.length){

			this.IMGS.css("cursor", "pointer");

			containerTmp.append(
				this.getTemp(this.IMGS.length)
			);

			this.GALLERY = $("#gallery");
			this.BODY    = $("body");

			this.setUpListeners();
		};

		return false;
	},
	setUpListeners: function(){

		this.IMGS.on("click", this.showHandler);

		this.GALLERY.on("click", ".close", this.hideHandler);
		this.GALLERY.on("click", ".zoom", this.zoomHandler);
		this.GALLERY.on("click", ".prev", this.prevHandler);
		this.GALLERY.on("click", ".next .image", this.nextHandler);

		$(window).on("keydown", this.keydownHandler);

		return false;
	},
	showHandler: function(){

		gallery.BODY.css({
			"overflow": "hidden",
			"margin-left": "-17px"
		});
		gallery.GALLERY.show();

		gallery.CURRENT = gallery.getImgPosition($(this));

		gallery.setImg($(this));

		return false;
	},
	hideHandler: function(){

		gallery.BODY.removeAttr("style");
		gallery.GALLERY.find(".image").html("");
		gallery.GALLERY.hide();

		return false;
	},
	zoomHandler: function(){

		var img = gallery.GALLERY.find(".image img"),
			src = img.attr("src");

		if(img.length){

			var tab = window.open(src, "_blank");
			tab.focus();
		};

		return false;
	},
	prevHandler: function(){

		var size = gallery.IMGS.size();

		if(gallery.CURRENT){

			gallery.CURRENT = --gallery.CURRENT;
		}else{

			gallery.CURRENT = --size;
		};

		gallery.setImg(
			gallery.IMGS.eq(gallery.CURRENT)
		);

		return false;
	},
	nextHandler: function(){

		var size = gallery.IMGS.size();

		if(gallery.CURRENT >= size - 1){

			gallery.CURRENT = 0;
		}else if(gallery.CURRENT){

			gallery.CURRENT = ++gallery.CURRENT;
		}else{

			gallery.CURRENT = 1;
		};

		gallery.setImg(
			gallery.IMGS.eq(gallery.CURRENT)
		);

		return false;
	},
	keydownHandler: function(event){

		if(gallery.GALLERY.css("display") == "block"){

			switch(event.keyCode){

				case 39:
					gallery.nextHandler();
					break;

				case 37:
					gallery.prevHandler();
					break;

				case 27:
					gallery.hideHandler();
					break;

				case 40:
					return false;
					break;

				case 38:
					return false;
					break;
			};
		};

		return false;
	},
	getTemp: function(length){

		var temp  = "<div id='gallery'>";

			if(length > 1){

				temp += "<div class='prev'>";
					temp += "<span class='icon'></span>";
				temp += "</div>";
			};

			if(length > 1){

				temp += "<div class='viewer next'>";
					temp += "<div class='image'>";
					temp += "</div>";
				temp += "</div>";
			}else{

				temp += "<div class='viewer'>";
					temp += "<div class='image'>";
					temp += "</div>";
				temp += "</div>";
			};

				temp += "<div class='close'>";
					temp += "<span class='icon'></span>";
				temp += "</div>";

				temp += "<div class='zoom'>";
					temp += "<span class='icon'></span>";
				temp += "</div>";

			temp += "</div>";

		return temp;
	},
	getImgPosition: function(img){

		var src = img.attr("src"),
			num;

		gallery.IMGS.each(function(i){

			if($(this).attr("src") == src){

				num = i;

				return false;
			};
		});

		if(num != undefined){

			return num;
		};

		return false;
	},
	setImg: function(img){

		var image = gallery.GALLERY.find(".image"),
			src    = img.attr("src"),
			alt    = img.attr("alt");

		image.html("<img src='" + src + "' alt='" + alt + "' />");

		return false;
	}
};

Объект состоит из четырёх свойств и одиннадцати методов. Давайте рассмотрим их подробнее:

  • IMGS – свойство, в котором хранятся все картинки;
  • GALLERY – свойство, в котором храниться jQuery объект выборки динамически добавленного HTML лайтбокса;
  • BODY – свойство, в котором храниться jQuery объект выборки элемента body;
  • CURRENT – номер выбранной картинки пользователем;
  • Initialize() – как выше было описано - точка входа;
  • setUpListeners() – функция, в которой мы отображаем все события скрипта;
  • showHandler() – обработка клика по картинке показ лайтбокса;
  • hideHandler() – обработка клика для закрытия лайтбокса;
  • zoomHandler() – отслеживание события клика по кнопке открытия картинки в новом окне;
  • prevHandler() – левая навигация;
  • nextHandler() - правая навигация (реализуется по нажатию на изображение);
  • keydownHandler() – обработка клавиш на клавиатуре (стрелки вправо и влево, esc, отключение стрелок вверх и вниз);
  • getTemp() – метод генерации шаблона галереи;
  • getImgPosition() – получение текущей выбранной картинки;
  • setImg() – установка изображения.

В конце страницы останется только запустить сам скрипт:

gallery.initialize(
	$("body"),
	$("#content")
);

Весь код написан таким образом, что, в дальнейшем, может быть легко модернизирован. К примеру, если потребуется добавить какой-нибудь красивый эффект смены картинок, то путем внесения изменений в метод setImg() этого легко можно будет добиться. Так же данный скрипт можно установить на различные CMS: Joomla, WordPress или другие.

Реклама
Комментариев еще не оставлено
no_avatar
Читайте далее

Waves - волна под курсором

21 мая 2015 Антон Кулешов

Эффекты при клике не столь популярны как hover effects, однако, сегодня мой взор упал на плагин под названием waves.

Галерея на jQuery «не только лишь» для фото и видео

6 марта 2015 Антон Кулешов

Fotorama - мощная и многофункциональная галерея, написанная на jQuery. Сразу скажу, скрипт довольно большой, так как включает в себя универсальное решение практически любой галереи или слайдера фотографий. Отсюда и вес плагина - 101кб, к сравнению, библиотека jQuery занимает примерно 250кб пространства на хостинге.

О том, как скачать видео с Ютуба и Вк

27 января 2016 Антон Кулешов

Оставим ненадолго серьёзные темы аутентификаций через социальные сети и сегодня я расскажу об очень приятном сервисе, который позволяет скачивать аудио и видео контент там, где это невозможно стандартными методами. Кнопка скачать попросту отсутствует на Ютубе, ВКонтакте, Фейсбук и куче других популярных сервисов. Конечно, продвинутый пользователь может скачать видео или аудио стандартными средствами браузера, но это сложно.