SiteIS

jQuery - безграничные возможности в дизайне Вашего сайта!

- Один из самых популярных на сегодня среди веб разработчиков фреймворк

- Позволяет быстро и легко создать потрясающие веб-приложения

- Удивительно красивые анимационные эффекты

- Улучшение пользовательского интерфейса

Слайдер с прокруткой (карусель)

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

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

html разметку в этот раз немного усложним - будем прокручивать не просто картинки, а блоки в которых помимо изображений присутствует текст. Ну и еще одно изменение коснется кнопок прокрутки. Их мы тоже добавим непосредственно в разметку, а не с помощью js, как это делали в предыдущем примере. Вот что получится в итоге:

<div class="carousel_wrap">	
	<span class="prev">prev</span>
	<span class="next">next</span>		
	<div class="visual_block">
		<ul>
			<li>
				<img src="/slider_image1.jpg" alt="" />
				<div class="text">Подпись к фото 1</div>
			</li>
			<li>
				<img src="/slider_image2.jpg" alt="" />
				<div class="text">Подпись к фото 2</div>
			</li>
			<li>
				<img src="/slider_image3.jpg" alt="" />
				<div class="text">Подпись к фото 3</div>
			</li>
		</ul>
	</div>		
</div>

Всю конструкцию мы помещаем в общий контейнер с классом carousel_wrap. Кнопки оформляем с помощью элементов span. Контейнер с классом visual_block будет служить окном, в котором будет отображаться содержимое слайда, а сами слайды (оформим их в виде ненумерованного списка) должны будут располагаться друг за другом. Само собой, ограничений на количество элементов LI нет.

Оформим внешний вид с помощью css:

.carousel_wrap  {
margin: 50px auto;
width:700px;
position:relative;
}
.visual_block {
margin: 0 auto;
position: relative;
overflow: hidden;
}
.visual_block ul {
position: relative;
}
.visual_block ul, .visual_block li {
float: left;
}

.carousel_wrap span.next, .carousel_wrap span.prev {
margin-top:-20px;
width:15px;
height:26px;
display:block;
text-indent:-9999px;
overflow:hidden;
cursor:pointer;
background:url(slider2_arrow.png) no-repeat;
position:absolute;
top:50%;
}
.carousel_wrap span.next {
right:0;
background-position:-15px 0;
}
.carousel_wrap span.next:hover {
background-position:-15px -26px;
}
.carousel_wrap span.prev:hover {
background-position:0 -26px;
}

Можно приступать к написаню js кода. Подумаем, как это можно сделать.

Сейчас все элементы LI расположены друг под другом. Что бы осуществить задуманное, нам потребуется выстроить их в один ряд, установить ширину блока visual_block равной ширине одного слайда (тогда отображаться будет только один элемент - все остальные обрежутся) и заставить слайды сдвигаться на эту же ширину через определенные промежутки времени. Удобнее всего будет, если размеры всех блоков будут высчитываться динамически. В jQuery подобное реализуется несколькими способами. Для нашего случая воспользуемся методами outerWidth() и outerHeight(). Эти методы вернут размеры отобранного элемента со всеми отступами. Ну и конечно, что бы было удобно оперировать значениями, будем сохранять их в переменных. Приступим.

Сначала объявим переменные для блоков оберток.

var elWrap = $('div.carousel_wrap'),
	visual = $('div.visual_block')
	carousel = visual.children('ul');

Далее добавим переменные visible (в ней будем хранить количество отображаемых блоков - в нашем случае это 1), itemWidth, itemHeight и itemsTotal (сюда положим значения ширины и высоты одного слайда, а так же их общее количество).

var elWrap = $('.carousel_wrap'),
	visual = $('.visual_block'),
	carousel = visual.children('ul'),
	visible = 1,	
	itemWidth = carousel.children().outerWidth(),
	itemHeight = carousel.children().outerHeight(),
	itemsTotal = carousel.children().length;

Теперь мы спокойно можем вычислить необходимые размеры контейнеров visual_block, visual_block ul и присвоить им нужные значения:

visual.css({'width': visible * itemWidth + 'px', 'height' : itemHeight});

carousel.css({'width': itemsTotal * itemWidth,	'left': 0});

Конструкция приобрела необходимый вид, но все еще не работает. Нужно заставить слайды двигаться (предположим, влево). Сделаем это, воспользовавшись методом animate, который будет смещать элемент UL влево.

carousel.animate({left: -itemWidth}, 500);

Тут мы применили метод animate к блоку UL и в параметрах указали, что блок нужно сдвинуть относительно левого края visual_block на расстояние, равное значению переменной itemWidth за промежуток времени 500 мл с. Что бы блок уехал в нужном направлении, переменной itemWidth задали отрицательное значение. К сожалению, такой записью желаемого результата добиться не удалось. Все, чего мы достигли, это смещение UL относительно visual_block всего один раз. Не беда, мы уже проделывали трюки с многократным повторением одного и того же действия (вспоминаем прошлый пример). Поступим так же и в этот раз. Создадим функцию, в которую "упакуем" нашу запись и будем вызывать ее с помощью метода setInterval, скажем, каждые три секунды.

function chengeLeft () {
	carousel.animate({left: -itemWidth}, 500);
}
setInterval(chengeLeft, 3000);

Снова неудача - смещение UL по прежнему происходит один раз. Оно и понятно. Мы же указали, что элемент требуется сдвинуть на itemWidth, задача выполнена и больше ничего не происходит. Последующие вызовы функции срабатывают в холостую. А что, если заставить UL возвращаться назад? Тогда каждый раз, когда будет вызываться функция элемент будет находиться в своем начальном положении. Попробуем. Возвращать элемент обратно нам нужно после того, как отработает animate. Вот и зададим ему в качестве третьего параметра так называемую callBack функцию, которая вернет UL в первоначальное положение.

function chengeLeft () {
	carousel.animate({left: -itemWidth}, 500, function() {
		carousel.css({"left": 0 });
	});
}
setInterval(chengeLeft, 3000);

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

На самом деле это не так. Нам просто нужно сделать еще несколько действий в callBack функции, а именно, клонировать первый элемент (который спрятался) и поместить клон в самый конец карусели, затем удалить этот элемент в начале карусели и только после этого вернуть UL на место. Осуществим задуманное.

function chengeLeft () {
	var item = carousel.children().eq(0);
	
	carousel.animate({left: -itemWidth}, 500, function() {
		item.clone().appendTo(carousel);
		item.remove();
		carousel.css({"left": 0 });
	});
}
setInterval(chengeLeft, 3000);

В функции chengeLeft объявляем переменную item, в которой будем хранить первый слайд. Затем в callBack функции клонируем слайд, перемещаем клон в конец карусели и удаляем сам элемент. В итоге нас ожидает полный успех. Мы запустили автоматическую прокрутку. Весь код теперь выглядит так:

$(document).ready(function(){
	var elWrap = $('.carousel_wrap'),
		visual = $('.visual_block'),
		carousel = visual.children('ul'),
		visible = 1,	
		itemWidth = carousel.children().outerWidth(),
		itemHeight = carousel.children().outerHeight(),
		itemsTotal = carousel.children().length;

	visual.css({'width': visible * itemWidth + 'px', 'height' : itemHeight});
	
	carousel.css({'width': itemsTotal * itemWidth,	'left': 0});
	
	function chengeLeft () {
		var item = carousel.children().eq(0);

		carousel.animate({left: -itemWidth}, 500, function() {
			item.clone().appendTo(carousel);		
			item.remove();
			carousel.css({"left": 0 });		
		});
	}	
	
	setInterval(chengeLeft, 3000);	
});

Скачать готовый код примера можно по ссылке ниже:

Скачать готовый код

В следующей статье мы закончим работу над слайдером - каруселью, заставив работать кнопки навигации.