jQuery → jQuery UI Range Slider - фиксим наложение ползунков друг на друга

Не раз пригождался этот плагин при создании расширенного фильтра в каталоге, но, как мне кажется, поведение этого плагина не совсем логично:

Ползунки пересекаются - левый ползунок всегда заезжает под правый. Конечно, это легко объясняется тем, что значения диапазона меняются на расстояние между центров ползунков, а когда центры совмещаются, то и совмещаются сами ползунки, а что если изображения ползунков не одинаковые, например, направленные друг к другу стрелки - результат будет не совсем красивым.

Решение №1 (не очень хорошее)

В сети часто встречается решение, когда анимация движения ползунка отключается при достижении определенного значения, одной из границ диапазона. На событие slide навешивается, например, такая функция:

  1. $( "#slider-range" ).slider({
  2. range: true,
  3. min: 0,
  4. max: 500,
  5. values: [ 75, 300 ],
  6. slide: function(event, ui) {
  7. if ( (ui.values[0] + 39) >= ui.values[1] ) {
  8. return false;
  9. }
  10. }
  11. });​

У данного подхода есть несколько существенных минусов:

  • Либо анимация заканчивается прежде, а изменение диапазона продолжается. Либо анимация и изменение диапазона прекращаются одновременно, но нельзя сделать значение диапазона меньше определенной разницы между границами
  • При резких движениях мышью анимация может завершаться раньше времени
  • При разной ширине дива, в котором расположен слайдер, анимация должна прекращаться при разной минимальной разницей между границами - это видно во втором примере - ширина слайдера больше, чем в первом примере, при этом разницы в 39 единиц, чтобы состыковать ползунки, явно не достаточно.

Как видно не самое универсальное решение со своими косяками.

Решение №2

Чтобы исправить логику работы этого плагина, а так же избежать проблем, которые появляются при решении описанном выше, для меня стало очевидно, что необходимо исследовать исходный код плагина. Для решения необходимо найти именно те методы, которые отвечают за движение ползунков и подсчет значений, соответствующих положению ползунков. Пришлось немного попотеть, но решение, как понимаете, было найдено. По мере исправления одного метода, возникали проблемы в других. Чтобы не менять исходный код библиотеки, нужные методы я вынес в отдельный файл. В итоге получился скрипт, который нужно цеплять к сайту после подключения библиотеки jQuery UI. Сам скрипт fixslider.js и fixslider.min.js. Тестировал с версиями jQuery UI 1.8.16 и 1.9.1. Демо работы скрипта:

Важно: Этот скрипт делает поправки для слайдера только в горизонтальной ориентации (опция orientation: "horizontal").

UPD: Для вертикальной ориентации так же работает - пример здесь.

Заключение

Таким образом во втором решении исправлена логика работы плагина и устранены проблемы, которые присутствуют в первом решении:

  • анимация не глючит при резких движениях мышью;
  • работа слайдера не зависит от его ширины
  • теперь ползунки не пересекаются

Так же, для удобства, fixslider добавляет к каждому из ползунков свой класс - first-handle и second-handle.

На самом деле есть еще один вариант решения - с помощью CSS, но он так же влечет за собой проблему, которая решается только фиксингом самого плагина. Если кому-то интересно то могу описать вариант этого решения, но мне кажется можно теперь не заморачиваться с CSS, имея под рукой fixslider.js :)

Комментарии

Спасибо огромное очень помогло, но есть небольшое замечание.
В случае если .ui-widget-content имеет просто цветовую подложку то при движение ползунка она появляется не сразу, это связано с реализацией отрицательного смещения ползунков и увеличения ширины .ui-slider-handle, за счет чего вы добились такого эффекта.
С удовольствием буду наблюдать за развитием вашего плагина.

Рад, что помогло. Вы правы, пришлось раздвинуть ползунки в стороны на половину их ширины, но без всякого увеличения их собственной ширины. Ширина .ui-slider-handle может быть произвольной.
На счет подложки, такое поведение кажется вполне логичным, так как диапазон располагается строго между ползунков, а не между их центрами, как если бы slider работал по умолчанию. Соответственно подложка будет появляться при смещении ползунка от границы на расстояние большее его ширины, а не половины ширины.

Автор, ты гений просто!Красавчик вообще!все круто работает

Не работает на 1.11.4

очень нужная доработка.
Но я сталкнулась с проблемой: у меня несколько слайдеров на странице. И данное расширение корректно работает только на первом. На других ползунки сбились в левую часть и наложились (как будто испугались)))), необходимо двинуть один из ползунков и тогда плагин прогрузится и ползунки будут на своих местах.

Как можно убрать этот непорядок? Может вы сможете подсказать?

Добрый день, я проверил, у меня есть пример работы и с несколькими слайдерами, все работает корректно:

Очень полезно, спасибо)

Пожалуйста, рад, что помог :)

на новых версиях jquery (например 1.9.1) не работает (

пардон, все работает, забыл поменять версию jquery ui на 1.9...

Добавить комментарий