Всем привет!
В сети огромное количество плагинов для стилизации бегунка (скролла) прокрутки контента.
Все они имеют минусы, порой весьма серьёзные минусы. Поэтому использование кастомных скроллов в больших и сложных проектов сводиться на нет.
За свое ничтожное время работы front-end разработчиком я перепробовал огромное количество плагинов и потратил кучу времени и нервов поиске/написании костылей для них.
Решение было одно, написать свой настоящий плагин.
И, кажется, у меня получилось!
Итак, идеальная прокрутка (скролл в дальнейшем) должна:
- адаптироваться под контент сама, без вызова процедур
- работать во всех браузерах
- CSS отдельно, javascript отдельно
- вести лог отладочной информации
- полная настройка внешнего вида бегунка, беговой дорожки и кнопок для прокрутки
- максимально на сколько это возможно эмулировать стандартный скролл
- простое использование
- подключил и забыл
Один из замечательных плагинов по прокрутке это jScrollPane. Но использование его в крупных проектах не реально. Если на адаптивной/резиновой странице/интерфейсе не одна дюжина блоков с прокруткой, то при изменении (event resize) окна браузера начинаются суровые тормоза.
Вдобавок ко всему, если в каждый блок добавляется контент по клику на кнопку, к примеру через AJAX, плагин приходиться вновь перезапускать чтобы подстроится под новую ширину контента. Это уже дополнительные строки кода и возможно баги.
По скольку javascript существенно отстает по производительности от языка на котором написан нативный браузерный скролл, то некоторые моменты пришлось опустить.
Если не повторять ошибки аналогичных плагинов, то от адаптации скрола при изменения окна браузера придется отказаться. Однако как адаптировать скролл для корректной прокрутки при/после изменении окна? Решение оказалось простым благодаря мощности javascript.
Идея плагина в событийно-ориентированном подходе. Скролл нужен для прокрутки контента в то время когда курсор мыши находится на этом блоке. Значит и запускать его нужно по событию, к примеру mouseover. Что это дает? Не нужно перезапускать все плагины на странице при/после изменении ширины страницы, а запускать каждый по отдельности при наведении на него мышью. Это идеальное решение, по сколько на странице, Вы прокрутите только пару блоков, остальные могут не удосужиться Вашего внимания. При resize не будет ни каких вычислении что положительно скажется на производительности.
От слов к делу, подключение:
Подключите стили, в дальнейшем именно в этой табличке стилей вы настроите вид вашего скрола.
<link rel="stylesheet" type="text/css" href="/path/to/scroll.css" media="all" />
После библиотеки jQuery подключите сам плагин.
<script src="/path/to/jquery.scroll.min.js"></script>
После загрузки DOM:
new Scroll();
Посмотреть живой пример можно здесь.
Все опции плагина необязательны.
new Scroll({
horizontal: false, // если вам необходим горизонтальный скролл поставьте значение в true
drag_old: false, // если здесь указать строку с HTML, весь указанный код появится внутри ползунка
cls: ['scroll-wrap', 'scroll-pane', 'scroll-track', 'scroll-drag'], // указать свой классы для узлов, последовательность строгая!
step: 5, // скорость прокрутки
start: false, // запустить все скроллы при загрузке DOM
iDeviceSupport: true // отключить кастомный скролл в мобильных устройствах Apple, использовать стандартный
});
Зачем отключать скролл в Apple мобильных устройствах? Дело в том что скролл в этих девайсах ведет себя не совсем естественно. Наверно, нет этой Яблочной физики. В добавок скроллы на Apple устройствах весьма красивы и лаконичны, если они показаны. Поэтому отключение поддержки по желанию разработчика.
У плагина есть события которые возникают при каких либо действиях, к примеру при наведении мыши, прокручивании, достижении ползунка верхней/нижней мертвой точки.
Эти события можно делегировать и выполнять какие либо действия на Ваше усмотрение, а так же следить за поведением.
Приведу только некоторые из событии, остальное можно найти на по ссылкам ниже.
Событие возникает когда полузнок мыши достигает нижней мертвой точки.
$('body').on('scrolling.bottom', '.scroll', function(event, data){
console.dir(data); // получаем кучу полезной информации о событии
var content_box = $(this).find('.scroll-pane');
// далее подгружаем еще контент в этот блок, чтобы сделать блок «бесконечным»
$.ajax({
url:'path/to/content',
success:function(res){
content_box.append(res);
}
});
});
Для того чтобы загрузить контент до достижения нижней мертвой точки используйте:
data.tracking.dragBot — оставшиеся расстояние от нижнего края ползунка до мертвой точки.
Событие scrolling.top аналогично, за исключение того что оно вызывается при достижении верхней мертвой точки.
scrolling.create — возникает когда запускается скролл, обертывается контент и плагин готов для прокрутки содержимого
scrolling.scroll — возникает во время прокрутки
Всю документацию к плагину Вы можете найти на странице плагина, по ссылкам внизу.
Минусы плагина:
- в Ubuntu все современные браузеры не реагируют на user-select, текст при перетаскивании ползунка мышью выделяется. Решается путем добавления padding-right узлу с классом .scroll-pane или контентой обертке/контентентым тегам
- та же проблема в Opera на всех OS
- в IE 8 иногда дергается ползунок
- в IE 7 срывается прокручивание, прокрутка передается окну браузера.
- в FireFox срывается прокручивание если мышь Apple Magic Mouse (хотя это возможно баг FireFox)
- нельзя использовать горизонтальный и вертикальный скролл одновременно
- жду ваших тестов
В целом плагин получился замечательный и весьма конкурентно-способный, пользуемся в продакшен уже около полугода. Справляется фактически со всеми задачами, к решению которых он призван.
Пример использования на реальном проекте тут.
Страница на github и там же полная документация.
Страница на сайте разработчика.
Всем Спасибо и с наступающим!
Автор: exewebru