Мой первый JQuery плагин Carousel
jQuery
- Содержание
На днях открыл для себя популярный фреймворк JQuery. Он показался мне довольно простым и понятным. И через пару дней я уже написал плагин, в отсутствии нужного в Интернете.

Чтобы сразу стало понятно, о чем я пишу, посмотрите пример.
Необходимо было изобразить список маленьких картинок в виде галереи. Все варианты найденных аналогов я откинул, потому что они требовали одинакового фиксированного размера изображений.
Особенности
- Нефиксированные размеры элементов галереи
- Скрипт работает в горизонтальном и вертикальном режиме
- Выбранный элемент перемещается в центр галереи
- При наведении изменяется прозрачность
- Настройка параметров
- Режим автопрокрутки
Требования
Для работы скрипта, помимо библиотеки JQuery, требуется плагин ScrollTo.
Установка
HTML
<div class="carousel_horizontal"> <div class="botomButton"></div> <div class="topButton"></div> <div class="scroll"> <ul> <li class="current"><p>1</p><a href="#"><img src="img/thumb_01.jpg" alt="1" /></a></li> <li><p>2</p><a href="#"><img src="img/thumb_02.jpg" alt="2" /></a></li> <li><p>3</p><a href="#"><img src="img/thumb_03.jpg" alt="3" /></a></li> </ul> </div> </div>
JavaScript
jQuery(document).ready(function(){
jQuery('div.carousel_horizontal').carousel(options);
});
Здесь jQuery('.carousel_horizontal') - блок галереи, его структура указана выше.
Опции
- mode - режим работы, может быть 'horizontal' и 'vertical',
- fadeDuration - длительность hover эффекта в миллисекундах,
- transitionDuration - длительность перемещения в миллисекундах,
- step - шаг перемещения по клику на управляющие кнопки,
- opacity - прозрачность элементов галереи,
- center - установка в true центрирует выбранное изображение
- circular - круговой режим
- auto - автопрокрутка
- delay - период автоматической прокрутки
Браузеры
Работу скрипта проверял в браузерах: Intenet Explorer 6+, Mozilla Firefox 3.5, Opera 10, Chrome 4. Сообщите, если Carousel будет работать некорректно.
Исходный код
$.fn.carousel = function(opts) {
var defaults = {
mode: 'horizontal', // vertical or horizontal
fadeDuration: 300,
transitionDuration: 700,
step: 300,
opacity: 0.5,
circular: false,
auto: false,
delay: 3000,
center: false
};
var options = $.extend(defaults, opts);
return this.each(function() {
var $obj = $(this),
$topButton = $obj.children('div.topButton'),
$bottomButton = $obj.children('div.botomButton'),
$scrollDiv = $obj.children('div.scroll'),
$ul = $scrollDiv.children('ul'),
$li = $ul.children('li'),
$current = $ul.children('li.current'),
scrollLimit = 0,
position = 0,
timer = null;
// get gallery's size
$li.each(function(){
scrollLimit += (options.mode == 'horizontal') ?
$(this).outerWidth() : $(this).outerHeight();
});
if (options.mode == 'horizontal') {
$ul.width(scrollLimit);
}
else {
$ul.height(scrollLimit);
}
var max = (options.mode == 'horizontal') ?
$ul.outerWidth() - $scrollDiv.outerWidth() :
$ul.outerHeight() - $scrollDiv.outerHeight();
// hover effects
$li.hover(function() {
timer && clearInterval(timer);
$(this).siblings(':not(.current)').stop().fadeTo(options.fadeDuration, options.opacity);
}, function() {
timer = initTimer();
$(this).siblings().stop().fadeTo(options.fadeDuration, 1);
});
// scrolling gallery
var scrollingTo = function(destination) {
if (typeof destination == 'number') { // if pass x,y
$scrollDiv.stop().scrollTo( destination, options.transitionDuration );
}
else if(typeof destination == 'object') {
var x;
if (options.mode == 'horizontal') { // if gallery's item
x = destination.position().left - $ul.position().left;
x -= ($scrollDiv.outerWidth() - destination.outerWidth()) / 2;
}
else {
x = destination.position().top - $ul.position().top;
x -= ($scrollDiv.outerHeight() - destination.outerHeight()) / 2;
}
if (x < 0)
x = 0;
$scrollDiv.stop().scrollTo( x, options.transitionDuration );
position = x;
}
if (!options.circular){
$topButton.toggleClass('disabled', position <= 0);
$bottomButton.toggleClass('disabled', position >= max);
}
},
// scrolling automatically
initTimer = function(){
if (!options.auto) return null;
return setInterval(function(){
if (position == max)
position = 0;
else {
position += options.step;
if (position > max)
position = max;
}
scrollingTo(position);
}, options.delay);
}
// navigation button's events
$topButton.click(function(){
if (options.circular && position == 0)
position = max;
else {
position -= options.step;
if (position < 0)
position = 0;
}
scrollingTo(position);
});
$bottomButton.click(function(){
if (options.circular && position == max)
position = 0;
else {
position += options.step;
if (position > max)
position = max;
}
scrollingTo(position);
});
timer = initTimer();
// scroll to the current item
if ($current.length) {
scrollingTo($current);
}
// scroll to the middle at first
else if (options.center) {
$li.click(function(){
var $el = $(this);
$el.siblings().removeClass('current');
$el.addClass('current');
scrollingTo($el);
});
}
});
};
Примеры
Понравилась статья? Подпишись на RSS.
Советую почитать:
Форма поиска с фильтром
Скрытые возможности jQuery (часть 2)
Скрытые возможности jQuery
jQuery Slidermenu с ползунком
Комментарии
О появление картинки при клике не написал?
Ответитьклёвый плагин))
Все зависит от того как она должна появляться...
ОтветитьИногда не хочет перемещать в центр выбранную картинку. Нужно щелкнуть на другую, потом опять на нее. (Фаерфокс)
ОтветитьПрошу прощения, ложная тревога)
Ответитьнедосмотрел что срабатывает на крайних картинках, т.е. когда "проматывать" уже нечего
Все работает отлично)
Добрый день. А можно сделать автопрокрутку? Подскажите как.
ОтветитьДобавил автопрокрутку в пример
ОтветитьДобрый день, Александр. Автопрокрутка замечательная. Но пошаговая. А плавную можно сделать? И как?
ОтветитьДень добрый.
Для этого установите в опциях значения delay и transitionDuration равными. Затем в коде задайте линейное движение в двух строчках
$scrollDiv.stop().scrollTo( destination, options.transitionDuration, {easing: 'linear'} );Пока так, скоро обновлю версию плагина.
ОтветитьАлександр, это работает - но при условии, что "position +=" не "options.step" а "max". Я поставил доп. условие и все работает. Только возврат в нулевую позицию происходит с такой-же скоростью как и автопрокрутка. Как сделать возврат нулевым или максимум малым?
ОтветитьPS. Хотя, нет все нормально по "position +=" но прокрутка с с медленным возвратом как то не очень смотрится.
Ответитьвсе фото получаются равным размером, ввиде квадратика, в моём случаи нужно выводить кадры фильмов, картинки бывают разного размера, и не совсем красиво получиться если кадр широкого размера, попытался сдалать так, у класса .carousel_horizontal .scroll img {
Ответитьпрописал это height: 40px; а это width: 40px; удалил, теперь всё нормально все картинки по высоте нормально а ширина как есть, единственное часто можно заметить получается два ряда, как от этого можно избавиться?
Покажите пример, я не понял.
Ответить"..Сообщите, если Carousel будет работать некорректно..."
Чего-то у меня выбранные картинки не открываются в центре окна (IE).
ОтветитьВ Chrome 9 карусель не работает. Не корректно просчитывается width в <ul>.
ОтветитьХром получает размеры картинок после загрузки dom. Если прописать эти размеры вручную, галерея заработает.
ОтветитьПрописывать ширину вручную - не вариант т.к. количество фотографий в галерее меняется в зависимости от раздела. Может есть какое то решение для хрома?
Ответитьнеточно выразился "количество фотографий в галерее меняется в зависимости от раздела"
ОтветитьХотел сказать - фотографии подгружаются автоматически под фиксированную высоту блока.
Предложу вам несколько вариантов.
Ответить1. Прописать размер картинки в HTML коде, т.е. выводим средствами PHP (или используем др. язык) картинку в месте с размером. Это самый простой путь.
2. Поставить некоторую задержку и запускать скрипт карусели спустя пару сотен миллисекунд. Нестабильно.
3. Используйте загрузчик галереи. Например, вот этот. Когда загрузятся картинки, запускаем галерею.
Проблему решил первым способом, действительно так проще всего.
ОтветитьСпасибо за комментарии!
Как сделать карусель чтоб крутилась в круговую!
ОтветитьСмотрю на демо страницу плагина через firefox 5.0 - в горизонтальной карусели последняя фотка №22 почему-то всегда прыгает во второй ряд под рисунок №1 - и нарушается полностью работа слайдера - при кликах на картинки не появляется gallery_current.png, не корректно происходит сдвиг и т д. Это как то можно исправить? В опере 11.11 2-х рядов нет, но при клике на любой рисунок остается активным почему-то всегда рисунок №11, то же самое в експлорере.
Ответить