Простой слайдер для нескольких пунктов
В данном уроке мы сделаем простой слайдер для пунктов списка на основе анимаций CSS и jQuery. Идея для урока инспирирована слайдером продукции Aplle, где несколько товаров выскальзывают с использованием анимации. Мы трансформируем данную концепцию для онлайн магазина, чтобы представлять товары в разных категориях. Категории с небольшим количеством товаров отлично подходят к данному слайдеру. Конечно, для большого количества товаров такое решение далеко от оптимума, но для магазинов с небольшим ассортиментом слайдер станет отличным инструментом.
Разметка
В качестве разметки HTML будем использовать элемент div, который содержит несколько неупорядоченных списков. В них размещаются пункты и навигация с ссылками категорий. Каждый пункт имеет ссылку с изображением и заголовком h4.
<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>
CSS
Примечание: префиксы производителей браузеров опущены для большей наглядности кода.
Изначально нужно выводить первый список с пунктами, а остальные элементы li смещаем вправо за пределы области видимости. При нажатии на ссылку навигации пункты будут выскальзывать справа или слева, в зависимости от текущей позиции выбранной категории.
Сначала определим стили для контейнера, который будет иметь класс mi-slider. У него будет предустановлена высота, которая требуется для установки правильного положения элементов ul:
.mi-slider {
position: relative;
margin-top: 30px;
height: 490px;
}
Элемент ul будет позиционироваться абсолютно, чтобы списки располагались один над другим. Мы будем перемещать пункты списка но не сам список. Установим для свойства 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;
}
Когда JavaScript отключен мы сохраняем внешний вид (используем Modernizr):
.no-js .mi-slider ul {
position: relative;
left: auto;
bottom: auto;
margin: 0;
overflow: visible;
}
Для того, чтобы центрировать все пункты установим для свойство выравнивания текста по центру для элемента ul, а для пунктов списка свойство display:inline-block; и ширину 20%. Такое значение для ширины даст гарантию, что пункт поместится в списка и сохранит подвижность.
По умолчанию все пункты смещаются вправо. Используем значение 600%, так как его будет достаточно, чтобы убрать все из поля видимости. Также добавляем небольшую трансформацию для прозрачности:
.mi-slider ul li {
display: inline-block;
padding: 20px;
width: 20%;
max-width: 300px;
transform: translateX(600%);
transition: opacity 0.2s linear;
}
Без JavaScript смещения не требуется:
.no-js .mi-slider ul li {
transform: translateX(0);
}
Определим стили для содержимого пунктов списка. Обратите внимание на установку для свойства изображений max-width значения 100%. Таким образом обеспечивается целостность шаблона при масштабировании изображений в соответствии с размерами контейнера, который представляет собой наш элемент li с процентным значением ширины.
.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, так как шаблон позиционируется абсолютно. Мы центрируем навигацию устанавливая автоматические боковые поля и устанавливая максимальную ширину 800px:
.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;
}
Ссылки навигации будут иметь достаточные отступы и трансформироваться при наведении курсора:
.mi-slider nav a {
display: inline-block;
text-transform: uppercase;
letter-spacing: 5px;
padding: 40px 30px 30px 34px;
position: relative;
color: #888;
outline: none;
transition: color 0.2s linear;
}
.mi-slider nav a:hover,
.mi-slider nav a.mi-selected {
color: #000;
}
Класс mi-selected, так же как и класс mi-current для списка, будет устанавливаться с помощью JavaScript.
Добавим небольшую стрелку вверху. Используем псевдо классы :before и :after для создания двух треугольников с помощью рамок
.mi-slider nav a.mi-selected:after,
.mi-slider nav a.mi-selected:before {
content: '';
position: absolute;
top: -5px;
border: solid transparent;
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.mi-slider nav a.mi-selected:after {
border-color: transparent;
border-top-color: #fff;
border-width: 20px;
left: 50%;
margin-left: -20px;
}
.mi-slider nav a.mi-selected:before {
border-color: transparent;
border-top-color: #333;
border-width: 27px;
left: 50%;
margin-left: -27px;
}
Улучшим визуальное представление с помощью анимаций. Первая анимация увеличение масштаба пунктов первого списка. Анимация 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;
}
Для нашего примера мы имеем максимум четыре пункта, поэтому и определены только четыре задержки. Если вам требуется большее количество пунктов, нужно определить большее количество задержек.
Для анимаций выскальзывания определяем четыре случая: два для выскальзывания нового пункта и два для убирания текущего пункта, в зависимости от направления. Определим четыре класса для списков, которые добавляются с помощью JavaScript:
/* Движение справа */
.mi-slider ul.mi-moveFromRight li {
animation: moveFromRight 350ms ease-in-out both;
}
/* Движение слева */
.mi-slider ul.mi-moveFromLeft li {
animation: moveFromLeft 350ms ease-in-out both;
}
/* Движение направо */
.mi-slider ul.mi-moveToRight li {
animation: moveToRight 350ms ease-in-out both;
}
/* Движение налево */
.mi-slider ul.mi-moveToLeft li {
animation: moveToLeft 350ms ease-in-out both;
}
Теперь нужно установить задержки анимации в зависимости от направления движения. Например, первый пункт выскальзывает без задержки, если он движется справа или убирается влево, а последний - при движении слева и уходе вправо.
.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;
}
Теперь определим сами анимации. Например, движение справа означает, что мы устанавливаем значение translateX равным 600% и смещаем его в 0. Движение налево означает установку конечной позиции в -600%, чтобы убрать пункт за пределы области видимости. И так далее:
@keyframes moveFromRight {
0% { transform: translateX(600%); }
100% { transform: translateX(0); }
}
@keyframes moveFromLeft {
0% { transform: translateX(-600%); }
100% { transform: translateX(0); }
}
@keyframes moveToRight {
0% { transform: translateX(0%); }
100% { transform: translateX(600%); }
}
@keyframes moveToLeft {
0% { transform: translateX(0%); }
100% { transform: translateX(-600%); }
}
И последнее по списку, но не по значимости: воспользуемся медиа запросами для выравнивания содержания слайдера на маленьких экранах.
Начнем с навигации. так как она должна сохраняться целостной в любых условиях:
@media screen and (max-width: 910px){
.mi-slider nav {
max-width: 90%;
}
.mi-slider nav a {
font-size: 12px;
padding: 40px 10px 30px 14px;
}
}
Так как мы установили фиксированную высоту слайдера, то ее нужно адаптировать:
@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;
}
}
Теперь пришло время переходить к jQuery.
JavaScript
Сделаем простой плагин для нашего слайдера. Большая часть работы выполняется в CSS, где определяются все анимации. Плагин сфокусирован на добавлении и убирании классов, а также на контроле за текущей выводимой категорией. Для браузеров, которые не поддерживают анимации используется метод "показать/скрыть".
Начнем с кеширования некоторых элементов и инициализации переменных:
_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 к ссылке категории под слайдером. Предполагаем, что индекс каждой ссылки соответствует индексу категории (элемент ul). При нажатии на ссылку пункты текущей категории убираются с экрана, а на их место выскальзывают новые один за другим (все анимации и задержки определены в CSS ).
_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;
};
Готово!
Источник: http://feedproxy.google.com/~r/ruseller/CdHX/~3/SIK-FN0pDU4/lessons.php
|
В данном уроке мы сделаем простой слайдер для пунктов списка на основе анимаций CSS и jQuery. Идея для урока инспирирована слайдером продукции Aplle, где несколько товаров выскальзывают с |
РэдЛайн, создание сайта, заказать сайт, разработка сайтов, реклама в Интернете, продвижение, маркетинговые исследования, дизайн студия, веб дизайн, раскрутка сайта, создать сайт компании, сделать сайт, создание сайтов, изготовление сайта, обслуживание сайтов, изготовление сайтов, заказать интернет сайт, создать сайт, изготовить сайт, разработка сайта, web студия, создание веб сайта, поддержка сайта, сайт на заказ, сопровождение сайта, дизайн сайта, сайт под ключ, заказ сайта, реклама сайта, хостинг, регистрация доменов, хабаровск, краснодар, москва, комсомольск |
Дайджест новых статей по интернет-маркетингу на ваш email
Новые статьи и публикации
- 2025-12-02 » Когда ошибка молчит: как бессмысленные сообщения ломают пользовательский опыт
- 2025-12-02 » 9 лучших бесплатных фотостоков
- 2025-12-02 » UTM-метки: ключевой инструмент аналитики для маркетолога
- 2025-12-02 » ПромоСтраницы Яндекса: Что такое и для чего служит
- 2025-12-02 » Метатеги для сайта: исчерпывающее руководство по Title, Description, Canonical, Robots и другим тегам
- 2025-11-26 » Оценка эффективности контента: превращаем информационный балласт в рабочий актив
- 2025-11-26 » 10 причин высокого показателя отказов на сайте
- 2025-11-26 » Когда и зачем обновлять структуру сайта
- 2025-11-26 » Скрытые демотиваторы: как мелочи разрушают эффективность команды
- 2025-11-26 » Зачем запускать MVP и как сделать это грамотно?
- 2025-11-20 » Половина российских компаний сократит расходы на транспорт и маркетинг в 2026 году
- 2025-11-20 » Перенос сайта с большим количеством ссылок
- 2025-11-20 » Перелинковка сайта: Что такое и как ее использовать
- 2025-11-20 » Критерии выбора SEO-специалиста и подрядчика для продвижения сайта
- 2025-11-20 » Применение искусственного интеллекта в рекламных агентствах: комплексное исследование трендов 2025 года
- 2025-11-19 » Геозапросы по-новому: как покорить локальное SEO с помощью ИИ
- 2025-11-14 » Консалтинг: сущность и ключевые направления
- 2025-11-14 » Онлайн-формы: универсальный инструмент для сбора обратной связи
- 2025-11-14 » Факторы конверсии органического трафика
- 2025-11-14 » Планирование рекламного бюджета: самостоятельный подход
- 2025-11-14 » Авторизация на сайте: как выбрать решение для удержания клиентов и сохранения продаж
- 2025-11-13 » Эффективные методы стимулирования клиентов к оставлению положительных отзывов
- 2025-11-13 » Налоговая реформа — 2026: грядущие изменения для предпринимателей
- 2025-11-13 » Альтернативы мессенджерам: что выбрать вместо Telegram и WhatsApp
- 2025-11-13 » Маркировка рекламы для начинающих: полное руководство по требованиям ЕРИР
- 2025-11-13 » ИИ не отберет вашу работу — её займет специалист, владеющий искусственным интеллектом
- 2025-10-29 » Как оценить эффективность работы SEO-специалиста: практическое руководство для маркетологов и владельцев бизнеса
- 2025-10-29 » Киберспорт как маркетинговый инструмент: стратегии привлечения геймеров
- 2025-10-29 » Как говорить с аудиторией о сложном
- 2025-10-29 » Что такое доказательства с нулевым разглашением (ZKP) и их роль в блокчейне
Лично я люблю землянику со сливками, но рыба почему-то предпочитает червяков. Вот почему, когда я иду на рыбалку, я думаю не о том, что люблю я, а о том, что любит рыба. (Дейл Карнеги / БИЗНЕС) |
Мы создаем сайты, которые работают! Профессионально обслуживаем и продвигаем их , а также по всей России и ближнему зарубежью с 2006 года!
Как мы работаем
Заявка
Позвоните или оставьте заявку на сайте.
Консультация
Обсуждаем что именно Вам нужно и помогаем определить как это лучше сделать!
Договор
Заключаем договор на оказание услуг, в котором прописаны условия и обязанности обеих сторон.
Выполнение работ
Непосредственно оказание требующихся услуг и работ по вашему заданию.
Поддержка
Сдача выполненых работ, последующие корректировки и поддержка при необходимости.


Мы создаем практически любые сайты от продающих страниц до сложных, высоконагруженных и нестандартных веб приложений! Наши сайты это надежные маркетинговые инструменты для успеха Вашего бизнеса и увеличения вашей прибыли! Мы делаем красивые и максимально эффектные сайты по доступным ценам уже много лет!
Комплексный подход это не просто продвижение сайта, это целый комплекс мероприятий, который определяется целями и задачами поставленными перед сайтом и организацией, которая за этим стоит. Время однобоких методов в продвижении сайтов уже прошло, конкуренция слишком высока, чтобы была возможность расслабиться и получать \ удерживать клиентов из Интернета, просто сделав сайт и не занимаясь им...
Мы оказываем полный комплекс услуг по сопровождению сайта: информационному и техническому обслуживанию и развитию Интернет сайтов.
Контекстная реклама - это эффективный инструмент в интернет маркетинге, целью которого является увеличение продаж. Главный плюс контекстной рекламы заключается в том, что она работает избирательно.