JScrollPane. Делаем красивый скроллинг
Несмотря на то, что Сеть переполнена рекомендациями не изменять привычный юзеру вид контроллов, все чаще приходиться сталкиваться с желанием заказчика увидеть на своем сайте необычный, красивый, а порой просто перекрашенный скроллбар.
Например, такой:
Задача
Реализовать вертикальный скроллбар, отвечающий следующим требованиям:
- соответствие дизайну;
- кроссбраузерность;
- возможность скроллить колесиком мыши.
Решение
Не будем изобретать велосипед, благо умные люди уже поработали за нас. Используем бесплатный плагин jScrollPane — он полностью отвечает перечисленным требованиям.
Update. Далее идет речь о первой версии данного плагина. Версии 2 посвящена отдельная статья JScrollPane 2 — настраиваемый скроллбар.
С помощью этого плагина можно сделать вот такой скролл или вот такой.
Проверено в:
- IE 6-8
- Firefox 3
- Opera 9.5-10
- Safari 3
Кому мало, можно посмотреть другие примеры на официальной странице плагина.
Что качать?
- библиотеку jquery
- (2.6 Kb) для поддержки скроллинга колесиком мыши.
- (22.62 Kb) собственно плагин.
- таблица стилей плагина.
- архивчик с примером картинок для скролла.
Быстрый старт
Подключаем библиотеки и не забываем про CSS:
<link type="text/css" rel="stylesheet" href="css/jScrollPane.css"/> <script type="text/javascript" src="js/jquery-1.4.2.min.js" ></script> <script type="text/javascript" src="js/jquery.mousewheel.min.js"></script> <script type="text/javascript" src="js/jScrollPane.js"></script>
Создаем в HTML контейнер для скролла:
<div class="scrollBox"> <div id="pane" class="scroll-pane"> Хочу себе необычный скролл! </div> </div>
В CSS задаем оформление контейнера:
.scroll-pane { width: 700px; /* Ширина видимой области*/ height: 275px; /* Высота видимой области*/ overflow: auto; /* Если отключены скрипты это правило позволит отобразить обычный скролл */ }
Настраиваем стили из jScrollPane.css и рисуем картинки (подробнее об этом ниже).
Последний шаг — инициализируем скролл скриптом:
<script type="text/javascript"> jQuery(function() { jQuery('#pane').jScrollPane({scrollbarWidth:18, showArrows:true}); }); </script>
А теперь обо всем подробнее
Подробнее о HTML
В примере выше создается два контейнера: scroll-pane и scrollBox, а используется фактически только scroll-pane. Для чего же нужен внешний контейнер scrollBox? Он пригодится для позиционирования области с прокруткой, так как спозиционировать сам scroll-pane достаточно трудно, ведь скрипт обернет его еще и своим собственным контейнером. Вообще говоря, использовать внешний див (у нас scrollBox) для позиционирования — это совет из официального сайта плагина.
Подробнее о CSS
Обещаный подробный разбор jScrollPane.css:
.jScrollPaneContainer { position: relative; overflow: hidden; z-index: 1; } /* Трек - полоса по которой бегает ползунок */ .jScrollPaneTrack { position: absolute; cursor: pointer; right: 0; top: 0; height: 100%; background: url(../images/scrollTrak.gif) repeat-y; /* задаем фоновую картинку или просто цвет фона */ } /* Средняя часть ползунка (резиновая, т.к. ползунок меняет высоту в зависимости от количества содержимого) */ .jScrollPaneDrag { position: absolute; background: url(../images/scrollDrag.gif) repeat-y; /* задаем фоновую картинку или просто цвет фона */ cursor: pointer; overflow: hidden; left:1px; } /* верхушка ползунка (можно задать height:0, если ползунок не имеет выраженной верхушки) */ .jScrollPaneDragTop { position: absolute; top: 0; left: 0; overflow: hidden; background: url(../images/scrollDragTop.gif) no-repeat; /* задаем фоновую картинку или просто цвет фона */ height:3px; /* высота верхушки */ } /* низ ползунка (можно задать height:0, если ползунок не имеет выраженного низа) */ .jScrollPaneDragBottom { position: absolute; bottom: 0; left: 0; overflow: hidden; background: url(../images/scrollDragBot.gif) no-repeat; /* задаем фоновую картинку или просто цвет фона */ height:3px; /* высота низа */ } /* стрелка вверх (правило можно исключить, если скролл по дизайну без стрелок) */ a.jScrollArrowUp { display: block; position: absolute; z-index: 1; top: 0; right: 0; text-indent: -2000px; overflow: hidden; height: 18px; /* высота стрелки (ширина определяется шириной скролла при инициализации скрипта) */ background: url(../images/arrow_up.gif) no-repeat; /* задаем фоновую картинку или просто цвет фона */ } /* стрелка ввниз (правило можно исключить, если скролл по дизайну без стрелок)*/ a.jScrollArrowDown { display: block; position: absolute; z-index: 1; bottom: 0; right: 0; text-indent: -2000px; overflow: hidden; height: 18px; /* высота стрелки (ширина определяется шириной скролла при инициализации скрипта) */ background: url(../images/arrow_down.gif) no-repeat; /* задаем фоновую картинку или просто цвет фона */ }
Подробнее о js
Определены две функции:
jScrollPane | инициализирует скролл, согласно заданным параметрам (список см. в таблице ниже). |
---|---|
jScrollPaneRemove | «деинициализация» — удаляет стильный скролл и восстанавливает стандартный. |
Прараметры jScrollPane()
Название функции | Описание функции | Тип данных |
---|---|---|
scrollbarWidth | ширина нестандартной полосы прокрутки в пикселях. Значение по умолчанию 10 | int |
scrollbarMargin | отступы слева от полосы прокрутки в пикселях. Значение по умолчанию 5 | int |
wheelSpeed | указывает, как быстро колесо мыши заставит контент прокручиваться в пикселях. Значение по умолчанию 18 | int |
showArrows | указывает, отображать ли стрелки на полосе прокрутки. Значение по умолчанию false | boolean |
arrowSize | высота стрелок если showArrows=true (если не задана, рассчитывается из CSS) | int |
animateTo | нужна ли анимация при вызове scrollTo и scrollBy. Значение по умолчанию false | boolean |
dragMinHeight | минимальная высота, при которой можно будет перетащить ползунок. Значение по умолчанию 0 | int |
animateInterval | Интервал в миллисекундах для обновления анимации scrollPane. Значение по умолчанию 100 | int |
animateStep | Расстояние, которое проходить ползунок за один шаг анимации. Значение по умолчанию 3 | int |
maintainPosition | Если вы хотите, чтобы полоса прокрутки сохраняла свое положение при переинициализации, тогда она не будет прокручиваться при добавлении большего количества контента. Значение по умолчанию true | boolean |
scrollbarOnLeft | Определяет, что полоса прокрутки должна появиться слева от контента (убедитесь, что CSS также отражает этот момент) | boolean |
reinitialiseOnImageLoad | Должен ли скрипт автоматически переинициализироваться при подгрузке картинок в контенте. Значение по умолчанию false | boolean |
Немного о динамике
В случае, если ширина (высота) скролла меняется динамически необходимо вызвать последовательно функции jScrollPaneRemove и jScrollPane.
Предположим, имеем такой CSS:
.scrollBox{ width:200px; } .scroll-pane { width: 100%; height: 100px; overflow: auto; }
Скрипт изменяет ширину scrollBox, тем самым автоматически меняя ширину .scroll-pane:
<script type="text/javascript"> jQuery('#more').click(function() { jQuery('.scrollBox').css('width','300px'); jQuery('#pane').jScrollPaneRemove(); jQuery('#pane').jScrollPane({scrollbarWidth:18, showArrows:true}); }); </script>
Проверено в:
- IE 6-8
- Firefox 3
- Opera 9.5-10
- Safari 3
Нюанс с прокруткой колесиком мыши
У jScrollPane есть одна интересная особенность. Если крутить скролл колесиком мыши, то после того, как все содержимое контейнера проскроллится, начинает крутиться основной скроллбар страницы (конечно если он имеется).
Судя по коду jScrollPane.js это сделано специально (а значит это не баг а фича). Но если эта особенность мешает, ее запросто можно отключить.
Лезем в код jScrollPane.js и находим там строки:
$container.bind( 'mousewheel', function (event, delta) { ...тра-та-та многабукофф... return !dragOccured; } );
Меняем return !dragOccured; на return false;
Все! Теперь колесико ведет себя более логично и не будет управлять основным скроллом страницы, пока курсор мыши не выйдет за пределы контейнера.
Прокрутка к нужной позиции (update by Евгений Рыжков)
Иногда требуется сразу (или по какому-то действию) прокрутить блок с таким скроллингом до определенной позиции. Для этого плагин имеет две (почему-то плохо описанные) функции:
- scrollTo
- прокрутить контент до указанной позиции. Позицию можно указать в px (считаем от верхней границы этого самого блока с прокруткой) или задать id — блок прокрутится до элемента с указанным id
- scrollBy
- прокрутить блок на указанное число пикселей относительно текущей позиции
Функции цепляются к блоку, на который вешалась инициализация скроллинга.
<script type="text/javascript"> jQuery('#pane').jScrollPane({scrollbarWidth:18, showArrows:true}); jQuery('#pane')[0].scrollTo(500); </script>
Обращу внимание, что "[0]" — это обязательно. Зачем оно — не знаю (желающим узнать копать код плагина), но без этого не работает.
Плюсы:
- адекватно работает во всех популярных браузерах;
- позволяет гибко настроить вид и поведение скролла;
- скролится колесиком мыши.
Минус:
- Не реализована горизонтальная прокрутка. В версии JScrollPane 2 этот минус убрали (дополнение от Igor Charly).
Выводы
Дельный плагин. Подходит для решения большинства задач по стилизации скроллов. Юзаем, не стесняемся.
Материал
- jquery plugin :: jScrollPane