JQuery Slider, как сделать «шаг» изменения размера - PullRequest
65 голосов
/ 09 июня 2009

Можно ли использовать JQuery Slider (ползунок диапазона / двойной ползунок) для получения нелинейных (не согласованных размеров "шага") значений?

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

|----|----|----|----|----|--------|--------|-------------------------|--------------------------|...
0   500  750  1000  1250 1500     2000     2500                      75000                      100000...

Например, я хочу получить следующий код JQuery:

var values = [0, 500, 750, 1000, 1250, 1500, 2000, 2500, 75000, 100000, 150000, 200000, 250000, 300000, 350000, 400000, 500000, 1000000];
var slider = $("#price-range").slider({
    orientation: 'horizontal',
    range: true,
    min: 0,
    max: 1000000,
    values: [0, 1000000],
    slide: function(event, ui) {
            var includeLeft = event.keyCode != $.ui.keyCode.RIGHT;
            var includeRight = event.keyCode != $.ui.keyCode.LEFT;
            slider.slider('option', 'value', findNearest(includeLeft, includeRight, ui.value));
            $("#price-amount").html('$' + ui.values[0] + ' - $' + ui.values[1]);
            return false;
    },
    change: function(event, ui) { 
        getHomeListings();
    }
});
function findNearest(includeLeft, includeRight, value) {
    var nearest = null;
    var diff = null;
    for (var i = 0; i < values.length; i++) {
            if ((includeLeft && values[i] <= value) || (includeRight && values[i] >= value)) {
                    var newDiff = Math.abs(value - values[i]);
                    if (diff == null || newDiff < diff) {
                            nearest = values[i];
                            diff = newDiff;
                    }
            }
    }
    return nearest;
}

Приведенный выше код не совсем работает, но функция привязки к сетке не работает.

Ответы [ 12 ]

53 голосов
/ 09 июня 2009

Не уверен, хотите ли вы, чтобы шкала ползунка была пропорциональна вашим значениям *, но если это так, я предоставил решение этой проблемы для кого-то еще, кто задал тот же вопрос. Вы можете найти мое решение здесь . По сути, я использую событие slide, которое запускается при перемещении ползунка для имитации пошагового перехода, но на основе пользовательского массива, определяющего шаги. Таким образом, он только позволяет вам «шагнуть» к предварительно заданным значениям, даже если они неравномерно распределены.

* Другими словами, если вы хотите, чтобы ваш слайдер выглядел так:

|----|----|----|----|----|----|----|
0   10   20  100  1000 2000 10000 20000

, затем перейдите к одному из других решений, но если вы хотите, чтобы ваш слайдер выглядел следующим образом (диаграмма не в масштабе):

|--|--|-------|-----------|-----------|--------------------|--------------------|
0 10 20     100         1000        2000               10000                20000

Тогда решение, с которым я столкнулся, может быть больше, чем вы ищете.


Редактировать: Хорошо, эта версия скрипта должна работать с двумя ползунками:

$(function() {
    var values = [0, 500, 750, 1000, 1250, 1500, 2000, 2500, 75000, 100000, 150000, 200000, 250000, 300000, 350000, 400000, 500000, 1000000];
    var slider = $("#price-range").slider({
        orientation: 'horizontal',
        range: true,
        min: 0,
        max: 1000000,
        values: [0, 1000000],
        slide: function(event, ui) {
            var includeLeft = event.keyCode != $.ui.keyCode.RIGHT;
            var includeRight = event.keyCode != $.ui.keyCode.LEFT;
            var value = findNearest(includeLeft, includeRight, ui.value);
            if (ui.value == ui.values[0]) {
                slider.slider('values', 0, value);
            }
            else {
                slider.slider('values', 1, value);
            }
            $("#price-amount").html('$' + slider.slider('values', 0) + ' - $' + slider.slider('values', 1));
            return false;
        },
        change: function(event, ui) { 
            getHomeListings();
        }
    });
    function findNearest(includeLeft, includeRight, value) {
        var nearest = null;
        var diff = null;
        for (var i = 0; i < values.length; i++) {
            if ((includeLeft && values[i] <= value) || (includeRight && values[i] >= value)) {
                var newDiff = Math.abs(value - values[i]);
                if (diff == null || newDiff < diff) {
                    nearest = values[i];
                    diff = newDiff;
                }
            }
        }
        return nearest;
    }
});

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


Редактировать 2: Хорошо, если интервал слишком преувеличен, когда вы используете истинные значения, вы можете использовать набор поддельных значений для ползунка, а затем искать реальное значение, которое соответствует, когда вам нужно использовать реальное значение (аналогично какие другие решения здесь предложены). Вот код:

$(function() {
    var trueValues = [0, 500, 750, 1000, 1250, 1500, 2000, 2500, 75000, 100000, 150000, 200000, 250000, 300000, 350000, 400000, 500000, 1000000];
    var values =     [0,   1,   2,    3,    4,    5,    6,    7,    10,     15,     20,     25,     30,     40,     50,     60,     75,     100];
    var slider = $("#price-range").slider({
        orientation: 'horizontal',
        range: true,
        min: 0,
        max: 100,
        values: [0, 100],
        slide: function(event, ui) {
            var includeLeft = event.keyCode != $.ui.keyCode.RIGHT;
            var includeRight = event.keyCode != $.ui.keyCode.LEFT;
            var value = findNearest(includeLeft, includeRight, ui.value);
            if (ui.value == ui.values[0]) {
                slider.slider('values', 0, value);
            }
            else {
                slider.slider('values', 1, value);
            }
            $("#price-amount").html('$' + getRealValue(slider.slider('values', 0)) + ' - $' + getRealValue(slider.slider('values', 1)));
            return false;
        },
        change: function(event, ui) { 
            getHomeListings();
        }
    });
    function findNearest(includeLeft, includeRight, value) {
        var nearest = null;
        var diff = null;
        for (var i = 0; i < values.length; i++) {
            if ((includeLeft && values[i] <= value) || (includeRight && values[i] >= value)) {
                var newDiff = Math.abs(value - values[i]);
                if (diff == null || newDiff < diff) {
                    nearest = values[i];
                    diff = newDiff;
                }
            }
        }
        return nearest;
    }
    function getRealValue(sliderValue) {
        for (var i = 0; i < values.length; i++) {
            if (values[i] >= sliderValue) {
                return trueValues[i];
            }
        }
        return 0;
    }
});

Вы можете возиться с числами в массиве values (которые представляют точки остановки ползунка), пока вы не разметите их так, как вам нужно. Таким образом, вы можете почувствовать, с точки зрения пользователя, что он скользит пропорционально значениям, но без преувеличения. Очевидно, что если ваши истинные значения создаются динамически, вам может потребоваться алгоритм создания значений ползунка вместо статического их определения ...

14 голосов
/ 15 февраля 2014

HTML:

<body>
   <p>
      Slider Value: <span id="val"></span><br/>
      Nonlinear Value: <span id="nlVal"></span><br/>
   </p>
   <div id="slider"></div>
</body>

JS:

    $(function() {
     var valMap = [0, 25,30,50,55,55,60,100];
     $("#slider").slider({
        // min: 0,
         max: valMap.length - 1,
         slide: function(event, ui) {
           $("#val").text(ui.value);
           $("#nlVal").text(valMap[ui.value]);
         }
     });
    });
7 голосов
/ 09 июня 2009

Один вариант для вас - использовать размер шага один и ссылаться на массив, содержащий выбранные вами значения. Начните с 0, до 20, получите массив [value_of_slider], чтобы получить ваше фактическое значение. Я недостаточно хорошо знаю ползунки, чтобы сказать вам, есть ли способ задать ему собственный набор значений.

6 голосов
/ 09 июня 2009

На основании приведенного выше ответа и обсуждения от @Seburdis и с использованием имен из вашего примера:

var prices_array = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 150, 200, 250, 500, 1000, 1500, 2000, 2500, 5000, 10000];

function imSliding(event,ui)
{
    //update the amount by fetching the value in the value_array at index ui.value
    $('#amount').val('$' + prices_arr[ui.value] + ' - $' + prices_arr[prices_arr.length - 1]); 
}

$('#slider-interval').slider({ min:0, max:values_arr.length - 1, slide: imSliding});
5 голосов
/ 29 декабря 2013

Я думаю, что могу предложить лучшее решение: Идея состоит в том, чтобы сохранить массив с моими действительными значениями отдельно от ползунка, затем установить атрибут step всегда равным 1 и позволить ползунку работать с index этого массива, а затем извлечь реальное значение из моих реальных данных массив. Надеюсь, что этот пример помогает: http://jsfiddle.net/3B3tt/3/

4 голосов
/ 03 ноября 2010

Кто-то опубликовал это на веб-сайте jQuery. См:

http://forum.jquery.com/topic/non-linear-logarithmic-or-exponential-scale-for-slider

и

http://jsbin.com/ezema

Это именно то, что у вас есть, но намного проще (например, 1 строка кода).

3 голосов
/ 19 сентября 2013

вот как я это сделал. демо здесь - http://janpatricklara.com/web/extra/jQueryUISliderUnevenSteps.html

есть массив желаемых значений

var amts=[50,100,150,200,225,250,300];

имеет приращение ползунка от 0 до длины массива с шагом 1. вывести значение из индекса массива вместо использования фактического значения ползунка.

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

$('#amtslider').slider({
    min:0,
    max:amts.length-1,
    step:1,
    value:0,
    change:function(event, ui){
        //alert(amts[$(this).slider("value")]);
        //alert($(this).slider("value"));
        $('#lbl_amt').val(amts[$(this).slider("value")]);
    },
    slide:function(event, ui){
        $('#lbl_amt').val(amts[$(this).slider("value")]);
    }
});
2 голосов
/ 11 октября 2012

Вот мое простое решение для нестандартного (не согласованного размера «шаг») двойного слайдера (вы можете изменить его на один слайдер, если идея станет понятной) мой слайдер называется «слайдер-евро», текстовая область называется сумма-евро, как вы можете видеть в коде. Идея состоит в том, чтобы иметь ползунок от 0 до 100 и массив («реальные значения») на 101 место. Значение слайдера понимается как место в этом массиве. Единственное, что вы должны ссылаться на массив, когда вы получаете значения ползунка. Вот мой пример:

    $(function() {
    var realvalues = [0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 15000, 20000, 25000, 30000, 35000, 40000, 45000, 50000, 55000, 60000, 65000, 70000, 75000, 80000, 85000, 90000, 95000, 100000, 105000, 110000, 115000, 120000, 125000, 130000, 135000, 140000, 145000, 150000, 155000, 160000, 165000, 170000, 175000, 180000, 185000, 190000, 195000, 200000, 205000, 210000, 215000, 220000, 225000, 230000, 235000, 240000, 245000, 250000, 255000, 260000, 265000, 270000, 275000, 280000, 285000, 290000, 295000, 300000, 310000, 320000, 330000, 340000, 350000, 360000, 370000, 380000, 390000, 400000, 450000, 500000, 550000, 600000, 650000, 700000, 750000, 800000, 850000, 900000, 1000000, 1500000, 2000000];

    $( "#slider-euro" ).slider({
    range: true,
    min: 0,
    max: 100,
    step: 1,
    values: [ 25, 50 ],
    slide: function( event, ui ) {
    $( "#amount-euro" ).val( realvalues[ui.values[ 0 ]] + " € - " + realvalues[ui.values[ 1 ]] + " €");
    }
    });
    $( "#amount-euro" ).val( realvalues[$( "#slider-euro" ).slider( "values", 0 )] + " € - " + realvalues[$( "#slider-euro" ).slider( "values", 1 )]+" €" );
    });
1 голос
/ 26 августа 2013

Мне пришлось сделать что-то похожее, и, хотя это поздний ответ, кто-то еще может встретиться с этой веткой, как и я, и найти свое решение полезным. Вот решение, которое я создал:

http://jsfiddle.net/YDWdu/

So apparently, postings containing links to jsfiddle "must be accompanied by code".
OK - here ya go, stackoverflow... Some lovely "code" for you.
1 голос
/ 14 июля 2010

, если минимальное и максимальное значения совпадают, значение ползунка не изменяется

изменить эту часть

        if (ui.value == ui.values[0]) {
            slider.slider('values', 0, value);
        }
        else {
            slider.slider('values', 1, value);
        }

в

        if ( ui.values[0] == ui.values[1] ) {
            slider.slider('values', 0, value);
            slider.slider('values', 1, value);
        }else{
            if (ui.value == ui.values[0]) {
                slider.slider('values', 0, value);
            }else {
                slider.slider('values', 1, value);
            }
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...