Добавить отступы к слайдеру пользовательского интерфейса jQuery

Есть ли простой способ добавить отступы к ползунку слайдера пользовательского интерфейса jQuery? Я бы хотел, чтобы ручка ползунка не доходила до концов стержня. Итак, если это обычный левый конец:

no padding
\/
[]------------------

Я хотел бы, чтобы он имел отступы на левом (и правом) конце:

padding of 10px for instance
\/
--[]----------------

Я пробовал это в файле css:

.ui-slider-horizontal { height: .8em; padding: 0 10px; }

Но кажется, что jQuery UI Slider использует полную ( outerWidth() ) ширину для определения диапазона скольжения ручки вместо ширины без заполнения. Я также пытался взломать код, заменив outerWidth() на width(), но это ничего не дало.

Я явно не хочу прибегать к взлому установки минимальных и максимальных значений. Значения всегда должны работать так, как ожидалось.

Какие-либо предложения?

Изменить:

После комментария pkauko; Я использую ползунок как элемент с тремя метками над ним:

   not                      very
important    important    important
----[]-----------[]----------[]----

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


person Decent Dabbler    schedule 01.10.2010    source источник
comment
Мне просто любопытно, почему вы хотите, чтобы это работало так? Разве что идея в том, что нельзя выставлять минимальные и максимальные значения вообще с помощью ползунка и не только внешнего вида. В противном случае это будет выглядеть так, как будто ползунок не работает должным образом, если он не находится в самом конце слайда, когда установлено минимальное или максимальное значение.   -  person pkauko    schedule 01.10.2010
comment
@pkauko: см. дополнение, которое я сделал к моему вопросу.   -  person Decent Dabbler    schedule 01.10.2010
comment
Ах, хорошо, теперь я понимаю, почему вы хотите, чтобы это работало так, как описано. Жаль, что я не могу помочь вам в достижении желаемого поведения. Однако у меня может быть идея, и я отвечу в ближайшее время.   -  person pkauko    schedule 01.10.2010
comment
@pkauko: хорошо, pkauko, с нетерпением жду любых ваших предложений. Заранее спасибо!   -  person Decent Dabbler    schedule 01.10.2010


Ответы (2)


Хорошо, я сам часто хотел этого, но у меня никогда не было мотивации сесть и что-то в этом роде. Поскольку вы спросили сейчас, я сел и взломал ползунок пользовательского интерфейса jQuery, чтобы добавить параметры заполнения, как вы просили.

Примечание. Я добавил его только для горизонтальных ползунков с одной ручкой. Остальные случаи не сложнее. У меня просто не было мотивации печатать и последующее тестирование, чтобы охватить случаи, которые, вероятно, сейчас не нужны.

Включите этот код после того, как вы включили исходный слайдер из пользовательского интерфейса jQuery. Расширение перезаписывает пару методов и добавляет параметры «paddingMin» и «paddingMax» в виджет Slider (значения должны быть числовыми и будут интерпретироваться как пиксели; очевидно, это также может быть легко расширено, чтобы принимать другие единицы измерения, но опять же подразумевал бы больше ввода/тестирования для незапрошенных в настоящее время случаев).

Простой пример использования:

$('#slider').slider({ paddingMin: 50, paddingMax: 100 });

Код взлома расширения (предоставляется как есть, не судитесь со мной):

(
    function($, undefined)
    {
        $.ui.slider.prototype.options =
            $.extend(
                {},
                $.ui.slider.prototype.options,
                {
                    paddingMin: 0,
                    paddingMax: 0
                }
            );

        $.ui.slider.prototype._refreshValue =
            function() {
                var
                    oRange = this.options.range,
                    o = this.options,
                    self = this,
                    animate = ( !this._animateOff ) ? o.animate : false,
                    valPercent,
                    _set = {},
                    elementWidth,
                    elementHeight,
                    paddingMinPercent,
                    paddingMaxPercent,
                    paddedBarPercent,
                    lastValPercent,
                    value,
                    valueMin,
                    valueMax;

                if (self.orientation === "horizontal")
                {
                    elementWidth = this.element.outerWidth();
                    paddingMinPercent = o.paddingMin * 100 / elementWidth;
                    paddedBarPercent = ( elementWidth - ( o.paddingMin + o.paddingMax) ) * 100 / elementWidth;
                }
                else
                {
                    elementHeight = this.element.outerHeight();
                    paddingMinPercent = o.paddingMin * 100 / elementHeight;
                    paddedBarPercent = ( elementHeight - ( o.paddingMin + o.paddingMax) ) * 100 / elementHeight;
                }

                if ( this.options.values && this.options.values.length ) {
                    this.handles.each(function( i, j ) {
                        valPercent =
                            ( ( self.values(i) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100 )
                            * paddedBarPercent / 100 + paddingMinPercent;
                        _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
                        $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
                        if ( self.options.range === true ) {
                            if ( self.orientation === "horizontal" ) {
                                if ( i === 0 ) {
                                    self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
                                }
                                if ( i === 1 ) {
                                    self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
                                }
                            } else {
                                if ( i === 0 ) {
                                    self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
                                }
                                if ( i === 1 ) {
                                    self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
                                }
                            }
                        }
                        lastValPercent = valPercent;
                    });
                } else {
                    value = this.value();
                    valueMin = this._valueMin();
                    valueMax = this._valueMax();
                    valPercent =
                        ( ( valueMax !== valueMin )
                        ? ( value - valueMin ) / ( valueMax - valueMin ) * 100
                        : 0 )
                        * paddedBarPercent / 100 + paddingMinPercent;

                    _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";

                    this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );

                    if ( oRange === "min" && this.orientation === "horizontal" ) {
                        this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
                    }
                    if ( oRange === "max" && this.orientation === "horizontal" ) {
                        this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
                    }
                    if ( oRange === "min" && this.orientation === "vertical" ) {
                        this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
                    }
                    if ( oRange === "max" && this.orientation === "vertical" ) {
                        this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
                    }
                }
            };

        $.ui.slider.prototype._normValueFromMouse =
            function( position ) {
                var
                    o = this.options,
                    pixelTotal,
                    pixelMouse,
                    percentMouse,
                    valueTotal,
                    valueMouse;

                if ( this.orientation === "horizontal" ) {
                    pixelTotal = this.elementSize.width - (o.paddingMin + o.paddingMax);
                    pixelMouse = position.x - this.elementOffset.left - o.paddingMin - ( this._clickOffset ? this._clickOffset.left : 0 );
                } else {
                    pixelTotal = this.elementSize.height - (o.paddingMin + o.paddingMax);
                    pixelMouse = position.y - this.elementOffset.top - o.paddingMin - ( this._clickOffset ? this._clickOffset.top : 0 );
                }

                percentMouse = ( pixelMouse / pixelTotal );
                if ( percentMouse > 1 ) {
                    percentMouse = 1;
                }
                if ( percentMouse < 0 ) {
                    percentMouse = 0;
                }
                if ( this.orientation === "vertical" ) {
                    percentMouse = 1 - percentMouse;
                }

                valueTotal = this._valueMax() - this._valueMin();
                valueMouse = this._valueMin() + percentMouse * valueTotal;

                return this._trimAlignValue( valueMouse );
            };
    }
)(jQuery);
person Thomas    schedule 01.10.2010
comment
Я видел в вашем редактировании, что вы хотите использовать его с предопределенными значениями привязки. Я еще не тестировал этот вариант использования, поэтому не могу гарантировать, что он работает. Я работаю над этим, хотя. РЕДАКТИРОВАТЬ: Неважно, видимо, моя реализация была достаточно надежной, чтобы покрыть этот случай. :) - person Thomas; 01.10.2010
comment
@Thomas: это работает блестяще! Большое спасибо! Снап особо не нужен, т.к. я использую min: 1, max: 3, который распределяет позиции равномерно, как уже есть. Но не возражайте против того, чтобы немного изменить его, и опубликуйте новую версию, если вам это нравится. :) Отличная работа до сих пор. Действительно мило! - person Decent Dabbler; 01.10.2010
comment
Немного рефакторил код, добавил поддержку вертикальных ползунков. - person Thomas; 01.10.2010
comment
@Thomas: серьезно круто! Вы сэкономили мне много работы, потому что иначе я бы сам копался в коде. И поскольку я еще не был знаком с виджетами jQuery и прочим, это легко заняло бы у меня больше дня работы. Помимо присуждения вам награды за лучший ответ; у тебя есть пейпал аккаунт? Я с радостью подарю вам немного пива! - person Decent Dabbler; 01.10.2010
comment
Конечно, я не откажусь от бесплатного пива. ;)[ ende(dot)mail(at)web(dot)de (да, точка в имени пользователя)] Между прочим, я подал заявку на загрузку патча в Git-репозиторий jQuery-UI. Однако понятия не имею, сколько времени занимает их процедура пересмотра. - person Thomas; 01.10.2010
comment
@fireeyedboy: О, вы используете @username, чтобы отправить кому-то сообщение? Я новичок в ТАК. - person Thomas; 01.10.2010
comment
О, нет, это просто моя глупая привычка убеждаться, что ты видишь, что это адресовано тебе. :)\ - person Decent Dabbler; 01.10.2010
comment
Черт, нажал на вход слишком рано. :( В любом случае, я перевел вам несколько евро. Но я только что понял, что на банковском счете, связанном с PayPal, нет средств, поэтому сначала мне придется пополнить его. :-/ - person Decent Dabbler; 01.10.2010
comment
Снова! Входить слишком рано. Пффф. Не мой день сегодня. ;-) Я прослежу, чтобы ты получил бесплатное пиво. :) Возможно, это займет пару дней. :-/ - person Decent Dabbler; 01.10.2010
comment
Ваше здоровье. ;) Рад, что смог помочь. - person Thomas; 01.10.2010
comment
@Thomas: Хорошо, рад слышать. Пожалуйста. Это было заслуженно. - person Decent Dabbler; 10.10.2010
comment
@Thomas - Кажется, должен быть более простой способ сделать это. Взгляните на мой вопрос, где я использую нелинейные добавочные значения - stackoverflow.com/questions/8646796/ - поэтому мне нужно остановить ползунок на последнем приращении (или сделать последнее приращение, которое игнорируется ) - person Jason; 27.12.2011
comment
У меня не работает, используя jQueryUI 1.8.23. Нет ошибок JS, но ползунок сломан. - person AnimaSola; 19.09.2013
comment
@AnimaSola: меня это не удивляет, так как этому коду уже 3 года. :) Попробуйте эту скрипту: jsfiddle.net/cx6AF. Подход немного отличается, но также менее инвазивен. Версия jQueryUI, используемая в скрипке, — 1.9.2. Я ожидаю, что это будет работать и с вашей версией. Я включил краткое описание того, как это работает, хотя оно настолько маленькое, что вы, вероятно, легко сможете в нем разобраться. - person Thomas; 23.09.2013

Будет ли «привязка к шагам» в сочетании с «несовместимыми» (неравномерными значениями привязки) минимальными и максимальными значениями желаемого эффекта? Я знаю, что это, скорее всего, приведет к преобразованию значений на стороне приложения, поскольку это, вероятно, не может быть получено с использованием значений, используемых сейчас, но вот «решение» «взломать и слэш», если оно работает.

Я предлагаю установить минимальное значение, скажем, 750. Значение привязки к 1200 и максимальное значение к 4050. Таким образом, самое низкое значение привязки будет на 450 выше минимального значения, и ползунок никогда не должен достигать крайнего левого края. То же самое для максимального значения: 3 x 1200 + 450 = 4050. Используемые здесь значения произвольны и приведены только для примера.

Не проверял это и понятия не имею, работает ли это, и я знаю, что это не то, что вы искали, а просто идея, которая пришла в голову, когда я проверил примеры того, как слайдер пользовательского интерфейса jquery работает на jqueryui.com.

Изменить: не мог отпустить это, и теперь я знаю, что это работает таким образом, что ползунок не достигает концов слайда. Вам просто нужно установить начальное значение соответствующим образом, чтобы ползунок не находился в одном конце или в другом при загрузке страницы.

person pkauko    schedule 01.10.2010
comment
Я не могу понять, зачем нужны эти значения (в данный момент я не очень сообразителен), но, похоже, они работают. Я также пробовал мин. 300, макс. 3900, шаг 1200, например, но это приводило к тому, что ручка выходила за пределы левой стороны. Хм, странно. Я разделю на 10, что в основном то же самое. И хотя я надеялся на решение, в котором мне не нужно было бы преобразовывать выбранное значение, я пока воспользуюсь этим. Спасибо! - person Decent Dabbler; 01.10.2010