JQuery Slider, как изменить размер шага

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

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

|----|----|----|----|----|--------|--------|-------------------------|--------------------------|...
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;
}

Код выше не работает точно, но функциональность привязки к сетке не работает.

Ответ 1

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

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

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

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

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

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


Изменить: Хорошо, эта версия script должна работать с двумя слайдерами:

$(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 (которые представляют точки остановки ползунка), пока вы не разделите их так, как вы хотите. Таким образом, вы можете почувствовать, с точки зрения пользователя, как будто оно скользит пропорционально значениям, но не преувеличивается. Очевидно, что если ваши истинные значения динамически создаются, вам может потребоваться разработать алгоритм для генерации значений ползунка вместо статического определения их...

Ответ 2

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]);
         }
     });
    });

Ответ 3

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

Ответ 4

Основываясь на приведенном выше ответе и обсуждении от @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

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

Ответ 7

Вот мое простое решение для настраиваемого (несовпадающего "шагового" размера) двойного слайдера (вы можете изменить его на один слайдер, если идея станет понятной) мой слайдер называется "слайдер-евро", текстовая область называется количеством-евро, как вы можете видеть в коде. Идея состоит в том, чтобы иметь ползунок от 0 до 100 и массив ( "realvalues" ) с 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 )]+" €" );
    });

Ответ 8

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

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

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

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

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

$('#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")]);
    }
});

Ответ 9

Если значения min и max одинаковы, значение ползунка не изменяется

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

        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);
            }
        }

Ответ 10

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

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.

Ответ 11

Просто измените значения.

$( "#price-range" ).slider({
        range: true,
        min: 1000,
        max: 300000000,
        /*step:1,*/
        values: [ 1000, 300000000 ],
        slide: function( event, ui ) {
            if(ui.values[0]<=100000 && ui.values[1]<=100000){
                $("#price-range").slider({step:10000});
            }else if(ui.values[0]<=300000 && ui.values[1]<=300000){
                $("#price-range").slider({step:25000});
            }else if(ui.values[0]<=1000000 && ui.values[1]<=1000000){
                $("#price-range").slider({step:50000});
            }else if(ui.values[0]<=2000000 && ui.values[1]<=2000000){
                $("#price-range").slider({step:100000});
            }else if(ui.values[0]<=5000000 && ui.values[1]<=5000000){
                $("#price-range").slider({step:250000});
            }else if(ui.values[0]<=10000000 && ui.values[1]<=10000000){
                $("#price-range").slider({step:500000});
            }else if(ui.values[0]<=20000000 && ui.values[1]<=20000000){
                $("#price-range").slider({step:1000000});
            }else if(ui.values[0]<=50000000 && ui.values[1]<=50000000){
                $("#price-range").slider({step:5000000});
            }else if(ui.values[0]<=50000000 && ui.values[1]<=50000000){
                $("#price-range").slider({step:10000000});
            }else if(ui.values[0]<=200000000 && ui.values[1]<=200000000){
                $("#price-range").slider({step:25000000});
            }else{
                $("#price-range").slider({step:100000000});
            }

            $("#mins").val( ui.values[0] );
            $("#maxs").val( ui.values[1] );

        }
    });

Ответ 12

В дополнение к @Broshi jsfiddle выше, вот код для пользовательского слайдера с отключенным диапазоном:

JQuery

var myData = [1,2,3,4,5,6,7,8,9,10,20,30,40,50,60,70,80,90,100,200,300,400,500,600,700,800,900,1000,2000,3000,4000,5000,10000,20000,30000,50000,100000,200000,500000,1000000,20000000,30000000];
slider_config = {
        range: false,
        min: 0,
        max: myData.length - 1,
        step: 1,
        slide: function( event, ui ) {
            // Set the real value into the inputs
            console.log(ui);
            $('#value').val( myData[ ui.value ] );
        },
        create: function() {
            $(this).slider('value',0);
        }
    };

$("#slider").slider(slider_config);

HTML:

<input id="value" />
<div id="slider"></div>