Слайдер с подпунктами для сайта на jQuery Слайдер с подпунктами для сайта на jQuery



 

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

 

ДЕМО
ИСХОДНИКИ

 

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

Шаг 1. HTML

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

<div id="mi-slider" class="mi-slider">
 <ul>
 <li><a href="#"><img src="images/1.jpg" alt="img01"><h4>Ботинки</h4></a></li>
 <li><a href="#"><img src="images/2.jpg" alt="img02"><h4>Туфли</h4></a></li>
 <li><a href="#"><img src="images/3.jpg" alt="img03"><h4>Мокасины</h4></a></li>
 <li><a href="#"><img src="images/4.jpg" alt="img04"><h4>Кроссовки</h4></a></li>
 </ul>
 <ul>
 <li><a href="#"><img src="images/5.jpg" alt="img05"><h4>Ремни</h4></a></li>
 <li><a href="#"><img src="images/6.jpg" alt="img06"><h4>Шляпы</h4></a></li>
 <li><a href="#"><img src="images/7.jpg" alt="img07"><h4>Очки</h4></a></li>
 <li><a href="#"><img src="images/8.jpg" alt="img08"><h4>Шарфы</h4></a></li>
 </ul>
 <ul>
 <li><a href="#"><img src="images/9.jpg" alt="img09"><h4>Свобода</h4></a></li>
 <li><a href="#"><img src="images/10.jpg" alt="img10"><h4>Роскошь</h4></a></li>
 <li><a href="#"><img src="images/11.jpg" alt="img11"><h4>Спорт</h4></a></li>
 </ul>
 <ul>
 <li><a href="#"><img src="images/12.jpg" alt="img12"><h4>Чемоданы</h4></a></li>
 <li><a href="#"><img src="images/13.jpg" alt="img13"><h4>Дорожные</h4></a></li>
 <li><a href="#"><img src="images/14.jpg" alt="img14"><h4>Для ноутбуков</h4></a></li>
 <li><a href="#"><img src="images/15.jpg" alt="img15"><h4>Портфели</h4></a></li>
 </ul>
 <nav>
 <a href="#">Обувь</a>
 <a href="#">Аксессуары</a>
 <a href="#">Часы</a>
 <a href="#">Сумки</a>
 </nav>
</div>

Следует заметить, что изначально нужно выводить первый список с пунктами, а остальные элементы li смещаем вправо за пределы области видимости.

Шаг 2. CSS

Нам необходимо определить общие стили для контейнера, который будет иметь класс mi-slider. Для него мы установим высоту, которая требуется для установки правильного положения элементов ul:

.mi-slider {
    position: relative;
    margin-top: 30px;
    height: 490px;
}

Нам необходимо перемещать пункты списка но при этом не сам список. Для этого установим для свойства pointer-events значение none, так как нам нужно чтобы на нажатие кнопки мыши реагировала ссылка текущего списка:

.mi-slider ul {
    list-style-type: none;
    position: absolute;
    width: 100%;
    left: 0;
    bottom: 140px;
    overflow: hidden;
    text-align: center;
    pointer-events: none;
}

Теперь рассмотрим свойство pointer-events для текущего списка нужно обновить, чтобы ссылки в содержании стали доступны для нажатия:

.mi-slider ul.mi-current {
    pointer-events: auto;
}

Заданные значения по умолчанию устанавливают, что все пункты смещаются вправо. Для этого нам необходимо использовать значение 600%, так как его будет достаточно, чтобы убрать все из поля видимости. Также необходимо добавить небольшую трансформацию для прозрачности:

.mi-slider ul li {
    display: inline-block;
    padding: 20px;
    width: 20%;
    max-width: 300px;
    transform: translateX(600%);
    transition: opacity 0.2s linear;
}

Теперь нам необходимо определить стили для содержимого пунктов списка. Следует заметить, что свойство max-width для изображений имеет значение 100%:

.mi-slider ul li a,
.mi-slider ul li img {
    display: block;
    margin: 0 auto;
}

.mi-slider ul li a {
    outline: none;
    cursor: pointer;
}

.mi-slider ul li img {
    max-width: 100%;
    border: none;
}

.mi-slider ul li h4 {
    display: inline-block;
    font-family: Baskerville, "Baskerville Old Face", "Hoefler Text", Garamond, "Times New Roman", serif;
    font-style: italic;
    font-weight: 400;
    font-size: 18px;
    padding: 20px 10px 0;
}

Создаем прозрачность при наведении курсора мыши:

.mi-slider ul li:hover {
    opacity: 0.7;
}

Наш шаблон имеет абсолютное позиционирование, по этому навигацию устанавливаем со значением свойства top.

.mi-slider nav {
    position: relative;
    top: 400px;
    text-align: center;
    max-width: 800px;
    margin: 0 auto;
    border-top: 5px solid #333;
}

Если отключен JavaScript то выводить навигацию не требуется:

.no-js nav {
    display: none;
}

Анимация scaleUp также включает перемещение пунктов в координату 0, так как нам нужно вывести их в поле обзора:

.mi-slider ul:first-child li,
.no-js .mi-slider ul li {
    animation: scaleUp 350ms ease-in-out both;
}

@keyframes scaleUp {
    0% { transform: translateX(0) scale(0); }
    100% { transform: translateX(0) scale(1); }
}

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

.mi-slider ul:first-child li:first-child {
    animation-delay: 90ms;
}

.mi-slider ul:first-child li:nth-child(2) {
    animation-delay: 180ms;
}

.mi-slider ul:first-child li:nth-child(3) {
    animation-delay: 270ms;
}

.mi-slider ul:first-child li:nth-child(4) {
    animation-delay: 360ms;
}

Теперь нужно установить задержки анимации в зависимости от направления движения.

.mi-slider ul.mi-moveToLeft li:first-child,
.mi-slider ul.mi-moveFromRight li:first-child,
.mi-slider ul.mi-moveToRight li:nth-child(4),
.mi-slider ul.mi-moveFromLeft li:nth-child(4) {
    animation-delay: 0ms;
}

Необходимо увеличивать задержки постепенно:

.mi-slider ul.mi-moveToLeft li:nth-child(2),
.mi-slider ul.mi-moveFromRight li:nth-child(2),
.mi-slider ul.mi-moveToRight li:nth-child(3),
.mi-slider ul.mi-moveFromLeft li:nth-child(3) {
    -webkit-animation-delay: 90ms;
    animation-delay: 90ms;
}

.mi-slider ul.mi-moveToLeft li:nth-child(3),
.mi-slider ul.mi-moveFromRight li:nth-child(3),
.mi-slider ul.mi-moveToRight li:nth-child(2),
.mi-slider ul.mi-moveFromLeft li:nth-child(2) {
    -webkit-animation-delay: 180ms;
    animation-delay: 180ms;
}

.mi-slider ul.mi-moveToLeft li:nth-child(4),
.mi-slider ul.mi-moveFromRight li:nth-child(4),
.mi-slider ul.mi-moveToRight li:first-child,
.mi-slider ul.mi-moveFromLeft li:first-child  {
    -webkit-animation-delay: 270ms;
    animation-delay: 270ms;
}

Обратите внимание, так как мы установили фиксированную высоту слайдера, то ее нужно адаптировать для просмотра на различных разрешениях:

@media screen and (max-width: 740px){
    .mi-slider {
        height: 300px;
    }

    .mi-slider nav {
        top: 220px;
    }
}

Последним подпунктом данного шага будет установка стилей так, чтобы ничего не скрывалось и все списки выводились один над другим:

@media screen and (max-width: 490px){
    .mi-slider {
        text-align: center;
        height: auto;
    }

    .mi-slider ul {
        position: relative;
        display: inline;
        bottom: auto;
        pointer-events: auto;
    }

    .mi-slider ul li {
        animation: none !important;
        transform: translateX(0) !important;
        padding: 10px 3px;
        min-width: 140px;
    }

    .mi-slider nav {
        display: none;
    }
}

С этим шагом закончили, перейдем к следующему.

Шаг 3. JavaScript

Мы будем использовать небольшой плагин jQuery. Данный плагин необходим для добавления и очистки классов, а также следить за текущей выводимой категорией. Для браузеров, которые не поддерживают анимации используется метод "показать или скрыть". Начнем с кэширования переменных:

_init : function( options ) {

	// Категории (ul)
	this.$categories = this.$el.children( 'ul' );
	// Навигация
	this.$navcategories = this.$el.find( 'nav > a' );
	var animEndEventNames = {
		'WebkitAnimation' : 'webkitAnimationEnd',
		'OAnimation' : 'oAnimationEnd',
		'msAnimation' : 'MSAnimationEnd',
		'animation' : 'animationend'
	};
	// Название анимации и события
	this.animEndEventName = animEndEventNames[ Modernizr.prefixed( 'animation' ) ];
	// Поддержка анимаций и событий
	this.support = Modernizr.csstransforms && Modernizr.cssanimations;
	// Если анимация проводится
	this.isAnimating = false;
	// Текущая категория
	this.current = 0;
	var $currcat = this.$categories.eq( 0 );
	if( !this.support ) {
		this.$categories.hide();
		$currcat.show();
	}
	else {
		$currcat.addClass( 'mi-current' );
	}
	// Текущая категория навигации
	this.$navcategories.eq( 0 ).addClass( 'mi-selected' );
	// Инициализация событий
	this._initEvents();

},

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

_initEvents : function() {

		var self = this;
		this.$navcategories.on( 'click.catslider', function() {
			self.showCategory( $( this ).index() );
			return false;
		} );

		// Сброс при измении размеров окна
		$( window ).on( 'resize', function() {
			self.$categories.removeClass().eq( 0 ).addClass( 'mi-current' );
			self.$navcategories.eq( self.current ).removeClass( 'mi-selected' ).end().eq( 0 ).addClass( 'mi-selected' );
			self.current = 0;
		} );

	},
	showCategory : function( catidx ) {

		if( catidx === this.current || this.isAnimating ) {
			return false;
		}
		this.isAnimating = true;
		// Обновляем выбранную навигацию
		this.$navcategories.eq( this.current ).removeClass( 'mi-selected' ).end().eq( catidx ).addClass( 'mi-selected' );

		var dir = catidx > this.current ? 'right' : 'left',
			toClass = dir === 'right' ? 'mi-moveToLeft' : 'mi-moveToRight',
			fromClass = dir === 'right' ? 'mi-moveFromRight' : 'mi-moveFromLeft',
			// Текущая категория
			$currcat = this.$categories.eq( this.current ),
			// Новая категория
			$newcat = this.$categories.eq( catidx ),
			$newcatchild = $newcat.children(),
			lastEnter = dir === 'right' ? $newcatchild.length - 1 : 0,
			self = this;

		if( this.support ) {

			$currcat.removeClass().addClass( toClass );

			setTimeout( function() {

				$newcat.removeClass().addClass( fromClass );
				$newcatchild.eq( lastEnter ).on( self.animEndEventName, function() {

					$( this ).off( self.animEndEventName );
					$newcat.addClass( 'mi-current' );
					self.current = catidx;
					var $this = $( this );
					// Решение для ошибки в Chrome
					self.forceRedraw( $this.get(0) );
					self.isAnimating = false;

				} );

			}, $newcatchild.length * 90 );

		}
		else {

			$currcat.hide();
			$newcat.show();
			this.current = catidx;
			this.isAnimating = false;

		}

	},
	// На основании http://stackoverflow.com/a/8840703/989439
	forceRedraw : function(element) {
		if (!element) { return; }
		var n = document.createTextNode(' '),
			position = element.style.position;
		element.appendChild(n);
		element.style.position = 'relative';
		setTimeout(function(){
			element.style.position = position;
			n.parentNode.removeChild(n);
		}, 25);
	}

}

$.fn.catslider = function( options ) {
	var instance = $.data( this, 'catslider' );
	if ( typeof options === 'string' ) {
		var args = Array.prototype.slice.call( arguments, 1 );
		this.each(function() {
			instance[ options ].apply( instance, args );
		});
	}
	else {
		this.each(function() {
			instance ? instance._init() : instance = $.data( this, 'catslider', new $.CatSlider( options, this ) );
		});
	}
	return instance;
};

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

Вот и все. Готово!

Материал взят из зарубежного источника - tympanus.net/codrops/2012/12/31/how-to-create-a-simple-multi-item-slider и представлен исключительно в ознакомительных целях.


Top

🔖 Выбор по тегам ×

💌 Написать сообщение ×

Все поля обязательны для заполнения!