Доброго времени суток, дорогие читатели. Простите, что так редко пишу в блог. Времени мало еще и лень докучает. Эту статью я планировал написать еще в январе 2015 года, но у меня не получилось. Сегодня я расскажу вам как создать простую карусель (слайдер) с помощью jQuery. Карусели бывают разные, но речь в статье пойдет именно о карусели фотографий. Хотя, полученные знания можно применить к чему угодно и сделать хоть карусель каруселей. Статья ориентирована на новичков. Кому интересно прошу под кат.
По сути, карусель отличается от слайдера только тем, что слайдер показывает в конкретный момент времени только один элемент списка, а карусель несколько. Хотя многие люди воспринимают и карусель и слайдер как один и тот же элемент интерфейса, только с разным дизайном. Мы будем делать карусель. Но полученные знания можно будет применить для создания слайдера. Хочу напомнить, что статья ориентирована на новичков и ее цель показать принцип работы и внутреннее устройство карусели/слайдера. В реальных проектах лучше использовать готовые решения (возможно собственной разработки), чем писать все самому. Хотя иногда и это имеет смысл.
Для начала создадим обычный документ html. Назовем его index.html:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Статья про создание простой jQuery карусели</title> </head> <body> </body> </html>
Теперь нам нужно создать структуру самой карусели. Пускай каждый элемент нашей jQuery карусели будет состоять из картинки и небольшого текста. Как-то так:
<body> <ul> <li><img src="image1.jpg"><p>Описание 1</p></li> <li><img src="image2.jpg"><p>Описание 2</p></li> <li><img src="image3.jpg"><p>Описание 3</p></li> <li><img src="image4.jpg"><p>Описание 4</p></li> <li><img src="image1.jpg"><p>Описание 5</p></li> <li><img src="image2.jpg"><p>Описание 6</p></li> <li><img src="image3.jpg"><p>Описание 7</p></li> <li><img src="image4.jpg"><p>Описание 8</p></li> <li><img src="image1.jpg"><p>Описание 9</p></li> <li><img src="image2.jpg"><p>Описание 10</p></li> <li><img src="image3.jpg"><p>Описание 11</p></li> <li><img src="image4.jpg"><p>Описание 12</p></li> </ul> </body>
Приведем немного нашу карусель в порядок простым CSS кодом. Для этого подключим сам CSS файл:
<head> <meta charset="UTF-8"> <title>Статья про создание простой jQuery карусели</title> <link rel="stylesheet" href="style.css"> </head>
Потом допишем классы к нашим элементам:
<body> <ul class="carousel-list"> <li class="carousel-element"><img src="image1.jpg"><p>Описание 1</p></li> <li class="carousel-element"><img src="image2.jpg"><p>Описание 2</p></li> <li class="carousel-element"><img src="image3.jpg"><p>Описание 3</p></li> <li class="carousel-element"><img src="image4.jpg"><p>Описание 4</p></li> <li class="carousel-element"><img src="image1.jpg"><p>Описание 5</p></li> <li class="carousel-element"><img src="image2.jpg"><p>Описание 6</p></li> <li class="carousel-element"><img src="image3.jpg"><p>Описание 7</p></li> <li class="carousel-element"><img src="image4.jpg"><p>Описание 8</p></li> <li class="carousel-element"><img src="image1.jpg"><p>Описание 9</p></li> <li class="carousel-element"><img src="image2.jpg"><p>Описание 10</p></li> <li class="carousel-element"><img src="image3.jpg"><p>Описание 11</p></li> <li class="carousel-element"><img src="image4.jpg"><p>Описание 12</p></li> </ul> </body>
И теперь самое главное, сам CSS код:
.carousel-list { list-style: none; } .carousel-element { display: block; margin-right: 25px; float: left; } .carousel-element img { max-width: 100px; }
Ничего не обычного. Зато страничка приобрела нормальный вид:
Сейчас наша будущая карусель похожа на простой список. Что бы она стала похожа на карусель, нужно завернуть ее в дополнительный блок (div), который скроет часть элементов. Этот блок я называю хайдер. Добавим его в html:
<body> <div class="carousel-hider"> <ul class="carousel-list"> <li class="carousel-element"><img src="image1.jpg"><p>Описание 1</p></li> ... <li class="carousel-element"><img src="image4.jpg"><p>Описание 12</p></li> </ul> </div> </body>
Теперь нужно сделать так, что бы ширина самого списка не была ограничена, а вот хайдер был с ограниченной шириной. Зачем это нужно, станет понятно чуть позже. Изменим для этого код самого списка:
.carousel-list { list-style: none; width: 10000px; }
А так же добавим код для хайдера:
.carousel-hider { width: 600px; overflow: hidden; }
Теперь получилось вот так:
Как видите, теперь часть элементов просто скрыта. Теперь нам нужно добавить элементы прокрутки. Это могут быть картинки (обычно стрелки) или просто текст. Мы добавим обычный текст. Для этого в html добавим строчки кода с нашими элементами управления:
<body> <div class="carousel-arrow-left"><span>Влево</span></div> <div class="carousel-hider"> <ul class="carousel-list"> <li class="carousel-element"><img src="image1.jpg"><p>Описание 1</p></li> ... <li class="carousel-element"><img src="image4.jpg"><p>Описание 12</p></li> </ul> </div> <div class="carousel-arrow-right"><span>Вправо</span></div> </body>
А после поправим CSS, что бы элементы управления каруселью нормально отобразились. Теперь весь CSS код будет выглядеть так:
.carousel-hider { width: 600px; overflow: hidden; float: left; } .carousel-list { list-style: none; width: 10000px; } .carousel-element { display: block; margin-right: 25px; float: left; } .carousel-element img { max-width: 100px; } .carousel-arrow-left, .carousel-arrow-right { float: left; }
Мы добавили атрибут float для элементов управления и самого хайдера. Кому-то может показаться странным зачем нужен floar со значением left для правого элемента управления. Дело в том, что если ему не задать float, он будет растягиваться на всю ширину пространства. В дальнейшем, когда мы захотим приукрасить элементы управления, это будет нам мешать.
Таким образом страница стала выглядеть вот так:
Как видите, есть лишнее пространство между левым элементом управления и хайдером. Кроме того, ширина хайдера рвет последний элемент блока. Что бы хайдер не рвал элементы, его ширина должна быть равна суммарной ширине всех видимых элементов списка. В нашей случае видимых элементов списка 5. Ширина каждого элемента 100 пикселей (по ширине картинки установленной в css), но еще у каждого элемента есть отступ в 25 пикселей с права. Его тоже нужно учесть. Но отступ от последнего элемента не нужен, так как там пустое пространство и видимым быть ему не обязательно. Кроме того, если мы в дальнейшем захотим приукрасить наши элементы управления («Влево» и «Вправо») лишний отступ внутри хайдера будет только мешать. Получается что хайдер должен быть шириной в 600 пикселей (я угадал). А лишнее пространство слева — это padding списка. Убираем его:
.carousel-list { list-style: none; width: 10000px; padding: 0px; }
Получилось вот что:
Приведем в порядок наши элементы управления. Пускай они будут похожи на кнопки:
.carousel-arrow-left, .carousel-arrow-right { float: left; display: block; border: 1px solid grey; background-color: lightgrey; padding: 5px; margin-top: 50px; } .carousel-arrow-left:hover, .carousel-arrow-right:hover { cursor: pointer; background-color: grey; } .carousel-arrow-left { margin-right: 25px; } .carousel-arrow-right { margin-left: 25px; }
Ничего особенного. Получилось вот так:
Наконец-то мы подошли к самому интересному. Осталось запрограммировать нашу карусель. Добавим в наш маленький учебный проект два JavaScript файла. Пустой файл slider.js и сам jQuery.js. Я использовал jQuery версии 2.1.3:
<head> <meta charset="UTF-8"> <title>Статья про создание простой jQuery карусели</title> <link rel="stylesheet" href="style.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <script src="slider.js"></script> </head>
Теперь, нам нужно повесить event’ы на наши элементы управления:
$(document).ready(function() { var leftUIEl = $('.carousel-arrow-left'); var rightUIEl = $('.carousel-arrow-right'); leftUIEl.click(function() { }); rightUIEl.click(function() { }); });
Что мы делаем дальше. Теперь, по клику на кнопку «Влево» или на кнопку «Вправо» мы будем изменять позицию нашего списка (ul) с помощью свойства left. В начальной позиции значение свойства left равно 0. Добавим свойство position для нашего списка, оно должно быть со значением relative:
.carousel-list { list-style: none; width: 10000px; padding: 0px; position: relative; }
Ширина каждого элемента списка — 125 пикселей, как мы уже посчитали выше. То есть, что бы прокрутить карусель на один элемент вправо, нужно задать значение left списка в -125 пикселей. А если мы хотим прокрутить влево, то просто 125 пикселей. На JS мы будем при каждом клике либо добавлять либо отнимать 125 пикселей. Для анимации прокручивания мы будем использовать функцию jquery — animate(..). Первые ее аргумент это массив параметров css для анимации, второй время анимации, третий callback (функция, которая выполниться после анимации). Получается вот так:
$(document).ready(function() { var leftUIEl = $('.carousel-arrow-left'); var rightUIEl = $('.carousel-arrow-right'); var elementsList = $('.carousel-list'); var pixelsOffset = 125; var currentLeftValue = 0; leftUIEl.click(function() { currentLeftValue += 125; elementsList.animate({ left : currentLeftValue + "px"}, 500); }); rightUIEl.click(function() { currentLeftValue -= 125; elementsList.animate({ left : currentLeftValue + "px"}, 500); }); });
На этом описание как создать самую простую карусель — заканчивается. Но в этой карусели есть баг. Если постоянно нажимать на кнопки — карусель будет постоянно прокручиваться. Даже если элементов уже нет, смещение списка будет происходить. Мы можем избежать этого. Если смещение равно 0, то кнопка «Влево» не должна срабатывать. Аналогично и для кнопки «Вправо». Добавим это в код:
$(document).ready(function() { var leftUIEl = $('.slider-arrow-left'); var rightUIEl = $('.slider-arrow-right'); var elementsList = $('.slider-list'); var pixelsOffset = 125; var currentLeftValue = 0; var elementsCount = elementsList.find('li').length; var minimumOffset = - ((elementsCount - 5) * pixelsOffset); var maximumOffset = 0; leftUIEl.click(function() { if (currentLeftValue != maximumOffset) { currentLeftValue += 125; elementsList.animate({ left : currentLeftValue + "px"}, 500); } }); rightUIEl.click(function() { if (currentLeftValue != minimumOffset) { currentLeftValue -= 125; elementsList.animate({ left : currentLeftValue + "px"}, 500); } }); });
Ну вот и все. Задавайте- свои вопросы.
Опишите логические действия в последних ваших изменениях, что конкретно означают добавленные вами события и для чего они служат последний раздел — «Но в этой карусели есть баг»
По моему я в статье это указал. Разве нет?
Зацените мой новый блог на английском. Ссылка в шапке сайта.
не плохо было бы готовую карусель выложить для скачивания
Пардон, тогда это не сделал, а сейчас файлов нет.
Зацените мой новый блог на английском. Ссылка в шапке сайта.
Почему не работает скрипт?
Укажите подробнее в чем именно беда.
Зацените мой новый блог на английском. Ссылка в шапке сайта.
Делал себе на сайт портфолио карусель, и столкнулся с такой же проблемкой. Ваш вариант работает, сам так сделал сначала, но потом, начав адаптировать, столкнулся с еще одним «багом». Область скрывающая карусель, разной длинны на определенных устройствах, и тут уже так решить её не выйдет.
Ну, моя карусель очень примитивная и больше для обучения. Для PRODaction кода лучше использовать готовые решения.
Зацените мой новый блог на английском. Ссылка в шапке сайта.
rgtfd
м?
Зацените мой новый блог на английском. Ссылка в шапке сайта.
Спасибо, очень хорошо все объяснено
Рад помочь!
Зацените мой новый блог на английском. Ссылка в шапке сайта.
не плохо было бы циклично сделать
Ну уже сейчас переделывать не буду 🙂
Зацените мой новый блог на английском. Ссылка в шапке сайта.
В последнем блоке ошибка
var leftUIEl = $(‘.slider-arrow-left’);
var rightUIEl = $(‘.slider-arrow-right’);
var elementsList = $(‘.slider-list’);
а нужно:
var leftUIEl = $(‘.carousel-arrow-left’);
var rightUIEl = $(‘.carousel-arrow-right’);
var elementsList = $(‘.carousel-list’);
2 часа над этим просидел)
Возможно, если вы правы, пардон.
Зацените мой новый блог на английском. Ссылка в шапке сайта.
Эмм… Не понял, почему-то не отправилось сообщение… Еще раз…
Я хотел спросить, можно ли сделать так, что бы на одной странице работало несколько каруселей, при этом не переписывая код под каждую? Как бы унифицировать код.
Можно. Нужно селектор изменить так, чтобы он реагировал на какой-то класс. А потом добавить к каждому элементу все нужные события через цикл по элементам этого класса.
Зацените мой новый блог на английском. Ссылка в шапке сайта.
не до конца понимаю логику 9й строки в последнем скрине. minimumOffset — по идее константа, так как длинна elementsCount = elementsList.find(‘li’).length — тоже не меняется от кликов. Итого, как может выполняться условие в 20й строке: if (currentLeftValue != minimumOffset) ??? оно ведь никогда и не будет выполняться, а значит смещение вправо будет происходить пока не пролистаем 10000рх.. Можете подробнее объяснить этот момент?
Я думаю объяснение вряд ли еще актуально, но если да дайте знать.
Зацените мой новый блог на английском. Ссылка в шапке сайта.
Уже разобрался. Спасибо за статью!
рад!
Хорошо бы модернизировать скрипт, чтобы можно было несколько каруселей на одной странице размешать, не зная наперед сколько их будет. Если число каруселей статично, то можно просто разные переменные для хранения данных использовать.
Скрипт был скорее для обучения, но спасибо за идею!
Зацените мой новый блог на английском. Ссылка в шапке сайта.
Спасибо чувак, все работает. Правда немного адаптировал скрипт, чтобы можно было вешать его на все карусели!
Пожалуйста!
Зацените мой новый блог на английском. Ссылка в шапке сайта.
//Циклично
$(document).ready(function() {
var leftUIEl = $(‘.carousel-arrow-left’);
var rightUIEl = $(‘.carousel-arrow-right’);
var elementsList = $(‘.carousel-list’);
var pixelsOffset = 125;
var currentLeftValue = 0;
var elementsCount = elementsList.find(‘li’).length;
var minimumOffset = — ((elementsCount — 5) * pixelsOffset);
var maximumOffset = 0;
leftUIEl.click(function() {
if (currentLeftValue != maximumOffset) {
currentLeftValue += 125;
elementsList.animate({ left : currentLeftValue + «px»}, 500);
} else {
currentLeftValue = minimumOffset;
elementsList.animate({ left : currentLeftValue + «px»}, 500);
}
});
rightUIEl.click(function() {
if (currentLeftValue != minimumOffset) {
currentLeftValue -= 125;
elementsList.animate({ left : currentLeftValue + «px»}, 500);
} else {
currentLeftValue = 0;
elementsList.animate({ left : currentLeftValue + «px»}, 500);
}
});
});
если кто будет копировать учтите, что кавычки «» необходимо заменить на «»
на лапки короче.
Круто!
Спасибо!
Зацените мой новый блог на английском. Ссылка в шапке сайта.
ЭТО НЕ КАРУСЕЛЬ С*** БЛ***
А что? 🙂
Зацените мой новый блог на английском. Ссылка в шапке сайта.
А как сделать авто прокрутку карусели
Вопрос еще актуален? 🙂
Зацените мой новый блог на английском. Ссылка в шапке сайта.
Циклично не работает. всё перепробовал выше.
Адаптации под мобильную версию нет.
А вот автоповорот работает с этим кодом:
$(document).ready(function() {
setInterval(function () {document.getElementById(«right»).click();}, 1000);
});
где 1000 это 1 секунда
Круто.
Под мобилку само собой нужно доделывать. Но я думаю для продакшена лучше готовое решение использовать.
Зацените мой новый блог на английском. Ссылка в шапке сайта.