imgShow - плагин для создания слайдшоу на jQuery

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

Сначала посмотрим результат, который у нас должен получиться.
Здесь вы можете написать что угодно. Или вообще ничего не писать! Можете использовать <strong>html</strong>-<i>теги</i> Или <a href="http://ilovetypography.com">ссылки</a> Даже сама картинка может быть ссылкой!
Теперь рассмотрим исходный код:
(function($){
	$.fn.imgShow = function(o){
		var o = $.extend({
			showPanel:'animate',
			timeShow: 3000,
			speedShow: 1000,
			speedHide: 1000,
			speedShowDesc: 500,
			speedHideDesc: 100
		}, o);
		return $(this).each(function(){
	    		var folder = $(this);
	    		var images = folder.find('img');
	    		var imgCount = images.length;
	       	        images.hide().each(function(i){
		    		$(this).attr('id','i_' + i);
			});
			var first = images.filter('#i_0');
			folder.width(first.width()).height(first.height());
			if (o.showPanel != 'none') {
				folder.append('<div class="desc"><div class="text">&nbsp;</div></div>'); 
				var desc = folder.children('.desc');
				var offset = folder.offset();
				desc.css('top', offset.top + 'px').css('left', offset.left + 'px').width(folder.width());
				if (o.showPanel == 'animate') desc.hide();
				var descText = desc.children('div');
			}
			var id;
			function ImgList() {
				id = id || 0;
				var currImg = images.filter('#i_' + id);
				currImg.fadeIn(o.speedShow,function(){
					if (o.showPanel != 'none') {
						var title = '';
						title = $(this).attr('alt');
						descText.html(title);
						if (title && o.showPanel == 'animate') desc.slideDown(o.speedShowDesc);
					}
					setTimeout(function(){
						if (o.showPanel == 'animate') {
							desc.slideUp(o.speedHideDesc);
						} 
						if (o.showPanel == 'always')  {
							descText.html('');
						}
						currImg.fadeOut(o.speedHide,function(){
							id ++; 
							if (id == imgCount) id = 0; 
							ImgList();
						});

					}, o.timeShow);
				});
			}
		    ImgList();
		});
	}
})(jQuery)
Кажется сложным?
Разберём код построчно:
(function($){ /* ... */ })(jQuery)
Данная строка позволяет использовать внутри функции знак доллара вместо строки jQuery.
Это необходимо для того, чтобы обеспечить совместимость плагина с другим кодом.
$.fn.imgShow = function(o){
	var o = $.extend({
		showPanel:'animate',
		timeShow: 3000,
		speedShow: 1000,
		speedHide: 1000,
		speedShowDesc: 500,
		speedHideDesc: 100
	}, o);
C помощью функции fn мы задаём имя новой функции – imgShow и переменную o, в которую будем получать настройки.
В следующих строках мы определяем настройки по умолчанию:
showPanel принимает 3 значения - «animate» (панель с описанием изображения появляется и исчезает вместе с изображением) и «always» (панель всегда сверху) и «none» (панель скрыта).
timeShow – количество миллисекунд(мс), которое картинка будет отображаться (по умолчанию 3000).
speedShow – количество мс, за которое появляется изображение (по умолчанию 1000).
speedHide – количество мс, за которое исчезает изображение (по умолчанию 1000).
speedShowDesc – количество мс, за которое появляется подпись к изображению (по умолчанию 500).
speedHideDesc – количество мс, за которое исчезает подпись к изображению (по умолчанию 100).
return $(this).each(function(){
	var folder = $(this); // сохраняем выбранный тег в переменную
	var images = folder.find('img'); // находим в нём все изображения
	var imgCount = images.length; // получаем количество изображений
	images.hide().each(function(i){
		$(this).attr('id','i_' + i); // к каждому изображению добавляем id, равный его порядковому номеру 
	});
Для чего мы пишем в начале функции return?
Чтобы продолжить при желании цепочку вызовов до или после вызова плагина.
Например, так:
$('.show').imgShow().css('padding': '30px');
В этом случае после вызова функции слайдшоу мы добавляем ко всем тегам с классом show отступ 30 пикселей.

Возвращаемся к нашему примеру.
var first = images.filter('#i_0'); // получаем первое изображение
folder.width(first.width()).height(first.height()); // присваиваем его размеры размерам родительского тега
if (o.showPanel != 'none') { // если нужно выводить панель
	folder.append('<div class="desc"><div class="text">&nbsp;</div></div>'); // создаём её
	var desc = folder.children('.desc'); 
	var offset = folder.offset();
	desc.css('top', offset.top + 'px').css('left', offset.left + 'px').width(folder.width()); // ставим панель на место
	if (o.showPanel == 'animate') desc.hide(); // если панель появляется только вместе с изображениями, убираем её
	var descText = desc.children('div'); // получаем блок, в который вставим описание картинки 
}
var id; // определяем id как глобальную переменную
function ImgList() {
	id = id || 0; 
	var currImg = images.filter('#i_' + id); // находим в списке изображений id с необходимым номером
	currImg.fadeIn(o.speedShow,function(){ // после того, как изображение появится, выполняем следующие действия
		if (o.showPanel != 'none') { // если мы показываем панель 
			var title = '';
			title = $(this).attr('alt'); // получаем описание из атрибута alt
			descText.html(title); // добавляем его на панель
			if (title && o.showPanel == 'animate') desc.slideDown(o.speedShowDesc); // показываем панель
		}
		setTimeout(function(){ // ждём определённое время
			if (o.showPanel == 'animate') {
				desc.slideUp(o.speedHideDesc); // скрываем панель
			} 
			if (o.showPanel == 'always')  {
				descText.html(''); // или убираем текст
			}
			currImg.fadeOut(o.speedHide,function(){ // прячем изображение
				id ++; // увеличиваем id для доступа к следующему изображению
				if (id == imgCount) id = 0; // если изображение было последним, возвращаемся к началу 
				ImgList(); // запускаем функцию заново
			});
		}, o.timeShow);
	});
}
ImgList(); // запускаем функцию
Функция ImgList нужна для того, чтобы слайдшоу было непрерывным.
Она вызывает саму себя, тем самым, уходя в бесконечную рекурсию. (Что такое рекурсия вы можете узнать здесь.)
Конечно, это не очень красивый вариант, но в данном случае единственно возможный.

Теперь посмотрим на HTML:
<script type="text/javascript" src="imgshow.jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
	$('.imgshow').imgShow();
})
</script>
<div class="imgshow">
	<img src="/upload/imgshow/0.jpg" alt="Здесь вы можете написать что угодно." />
	<img src="/upload/imgshow/1.jpg" alt="Или вообще ничего не писать!" />
	<img src="/upload/imgshow/2.jpg" alt="" />
	<img src="/upload/imgshow/3.gif" alt="Можете использовать &lt;strong&gt;html&lt;/strong&gt;-&lt;i&gt;теги&lt;/i&gt;" />
	<img src="/upload/imgshow/4.jpg" alt="Или &lt;a href=&quot;http://ilovetypography.com&quot;&gt;ссылки&lt;/a&gt;" />
	<a href="http://ilovetypography.com"><img src="/upload/imgshow/5.jpg" alt="Даже сама картинка может быть ссылкой!" /></a>
</div>
Сначала мы подключаем плагин, затем вызываем его.
В данном случае мы вызываем плагин с настройками по умолчанию.
Если вы хотите вызвать функцию с другими параметрами, то вы можете вписать их в любом количестве и в любом порядке.
Несколько примеров:
$('.imgshow').imgShow({showPanel:'none'}); // не показываем панель
$('.imgshow').imgShow({timeShow: 5000, speedShow: 500,	speedHide: 500}); // увеличиваем время показа картинки и уменьшаем время появления/скрытия
$('.imgshow').imgShow({showPanel:'animate', timeShow: 2000}); // показываем панель постоянно и уменьшаем время показа 
Небольшой совет: если вы уверены, что вы будете использовать только одно слайдшоу на странице, вместо атрибута class у тега div используйте атрибут id:
<div id="imgshow">
	<img ...
Главное, в этом случае не забудьте сменить $('.imgshow') на $('#imgshow').
CSS:
.show {
	background-color:#000;
}
.desc {
	height:30px;
	background-image:url('/upload/imgshow/bg_slide.png');
	position:absolute;
	color:#FFF;
}
.desc .text {
	padding:5px 20px;
}
.show img {/* Чтобы плагин нормально работал в Chrome, необходимо заменить длину и ширину на размеры ваших изображений */
	width:400px;
	height:200px;
}
Как видно, с CSS всё тоже довольно просто.
Первый урок по написанию плагинов в jQuery закончен :)
Если у вас есть вопросы, задавайте их в комментариях.
В следующем уроке мы рассмотрим, как можно добавить дополнительную функциональность нашему плагину – например, ручной переход по изображениям.


Комментарии

11 мая 2010, 19:01 (Ответить)
Вопрос: Сколько имиджей тянет скрипт? Работает ли без тормозов если имиджей скажем 100-200? Спасибо.
12 мая 2010, 9:51 (Ответить)
Jay, я на скорую руку сгенерировала 200 изображений и выложила слайдшоу из них здесь.
Ни в одном из браузеров (Firefox, Chrome, Opera, IE) особых тормозов не наблюдается.
12 мая 2010, 23:16 (Ответить)
Ok спасибо! Попробую у себя.
13 мая 2010, 1:31 (Ответить)
Нина, ты молодец! Спасибо, за твой скрипт он помог мне усовершенствовать собственный. Мой скрипт использовал opacity и animate и тормозил на большом количестве фоток в IE. Теперь я использую hide и далее feidIn faidOut и ничего не тормозит. Теперь проверю как обрабатывается z-index. Успехов!
13 мая 2010, 9:09 (Ответить)
Jay, спасибо.
Была рада помочь.
13 мая 2010, 1:33 (Ответить)
В смысле fadeIn fadeOut :)
11 ноября 2010, 7:58 (Ответить)
Сильные тормоза в IE 8.0 на Celeron 1.2Ghz
12 февраля 2011, 10:44 (Ответить)
Здрасти, а как можно применить данную технологию к фону в таблице?
Т.е у меняя в шапке сайта фоновый рисунок,хотелось бы что бы он плавно сменялся.Спасибо.
17 декабря 2011, 18:06 (Ответить)
Спасибо автору за замечательные статьи и действительно полезную информацию.
Буду и дальше читать ваш блог =)
9 марта, 18:08 (Ответить)
Здравствуйте, Нина.
Извините, вопрос не в тему, но вдруг...
у сайте раньше при нажатии на икону Николая изображение плавно увеличевалось до опеделенного размера. Экран не затемнялся.
Может вы знаете, как называется такой эффект увеличения... это у меня плагин стоял, я его нечаянно удалила, а названия не помню... и теперь нигде не могу найти - что это за эффект. Если ответите на почту, огромное спасибо.
20 апреля, 13:39 (Ответить)
Очень замечательный блог вы ведете. Интересные статьи. Успехов в творчестве и развитии.
7 мая, 3:24 (Ответить)
Спасибо за плагин. Было бы отлично, если бы подсказали, как его переделать под простой плагин для джумла, а также, какие еще эффекты и функции можно добавить.

Добавить комментарий