Мой первый JQuery плагин Carousel

  • Содержание

На днях открыл для себя популярный фреймворк 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);
                });
            }
        });

    };

Примеры

Пример
Скачать с github

Понравилась статья? Подпишись на RSS.

Советую почитать:

Форма поиска с фильтром
Скрытые возможности jQuery (часть 2)
Скрытые возможности jQuery
jQuery Slidermenu с ползунком

Теги: плагин карусель, jquery карусель

HTML + JSON jQuery Formwizard плагин

Комментарии

  • iNefor написал 24 июля 2010 года

    О появление картинки при клике не написал?
    клёвый плагин))

    Ответить
  • Александр написал 13 августа 2010 года

    Все зависит от того как она должна появляться...

    Ответить
  • Guybrush написал 25 августа 2010 года

    Иногда не хочет перемещать в центр выбранную картинку. Нужно щелкнуть на другую, потом опять на нее. (Фаерфокс)

    Ответить
  • Guybrush написал 25 августа 2010 года

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

    Ответить
  • Олег написал 08 сентября 2010 года

    Добрый день. А можно сделать автопрокрутку? Подскажите как.

    Ответить
  • Александр написал 12 сентября 2010 года

    Добавил автопрокрутку в пример

    Ответить
  • Олег написал 30 сентября 2010 года

    Добрый день, Александр. Автопрокрутка замечательная. Но пошаговая. А плавную можно сделать? И как?

    Ответить
  • Александр написал 30 сентября 2010 года

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

    $scrollDiv.stop().scrollTo( destination, options.transitionDuration, {easing: 'linear'} );

    Пока так, скоро обновлю версию плагина.

    Ответить
  • Олег написал 30 сентября 2010 года

    Александр, это работает - но при условии, что "position +="  не "options.step" а "max". Я поставил доп. условие и все работает. Только возврат в нулевую позицию происходит с такой-же скоростью как и автопрокрутка. Как сделать возврат нулевым или максимум малым?

    Ответить
  • Олег написал 30 сентября 2010 года

    PS. Хотя, нет все нормально по "position +=" но прокрутка с с медленным возвратом как то не очень смотрится.

    Ответить
  • Алексаньдер написал 01 декабря 2010 года

    все фото получаются равным размером, ввиде квадратика, в моём случаи нужно выводить кадры фильмов, картинки бывают разного размера, и не совсем красиво получиться если кадр широкого размера, попытался сдалать так, у класса  .carousel_horizontal .scroll img {
    прописал это height: 40px; а это width: 40px; удалил, теперь всё нормально все картинки по высоте нормально а ширина как есть, единственное часто можно заметить получается два ряда, как от этого можно избавиться?

    Ответить
  • Александр написал 01 декабря 2010 года

    Покажите пример, я не понял.

    Ответить
  • Юрий М написал 08 января 2011 года

    "..Сообщите, если Carousel будет работать некорректно..."

    Чего-то у меня выбранные картинки не открываются в центре окна (IE).

    Ответить
  • Алексей написал 13 февраля 2011 года

    В Chrome 9 карусель не работает. Не корректно просчитывается width в <ul>.

    Ответить
  • Александр написал 13 февраля 2011 года

    Хром получает размеры картинок после загрузки dom. Если прописать эти размеры вручную, галерея заработает.

    Ответить
  • Алексей написал 15 февраля 2011 года

    Прописывать ширину вручную - не вариант т.к. количество фотографий в галерее меняется в зависимости от раздела. Может есть какое то решение для хрома?

    Ответить
  • Алексей написал 15 февраля 2011 года

    неточно выразился "количество фотографий в галерее меняется в зависимости от раздела"
    Хотел сказать - фотографии подгружаются автоматически под фиксированную высоту блока.

    Ответить
  • Александр написал 15 февраля 2011 года

    Предложу вам несколько вариантов.
    1. Прописать размер картинки в HTML коде, т.е. выводим средствами PHP (или используем др. язык) картинку в месте с размером. Это самый простой путь.
    2. Поставить некоторую задержку и запускать скрипт карусели спустя пару сотен миллисекунд. Нестабильно.
    3. Используйте загрузчик галереи. Например, вот этот. Когда загрузятся картинки, запускаем галерею.

    Ответить
  • Алексей написал 16 февраля 2011 года

    Проблему решил первым способом, действительно так проще всего.
    Спасибо за комментарии!

    Ответить
  • Дмитрий написал 21 февраля 2011 года

    Как сделать карусель чтоб крутилась в круговую!

    Ответить
  • Рома написал 11 июля 2011 года

    Смотрю на демо страницу плагина через firefox 5.0 - в горизонтальной карусели последняя фотка №22 почему-то всегда прыгает во второй ряд под рисунок №1 - и нарушается полностью работа слайдера - при кликах на картинки не появляется gallery_current.png, не корректно происходит сдвиг и т д. Это как то можно исправить? В опере 11.11 2-х рядов нет, но при клике на любой рисунок остается активным почему-то всегда  рисунок №11, то же самое в експлорере.

    Ответить