it-swarm.com.ru

JQuery Slider, как сделать "шаг" изменения размера

Можно ли использовать 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;
}

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

63
TomHankers

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

53
Alconja

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

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

7
Seburdis

Основываясь на ответе выше и обсуждении от @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});
6
karim79

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

5
Broshi

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

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

а также

http://jsbin.com/ezema

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

4
Nitroware

вот как я это сделал. Демо здесь - 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")]);
    }
});
3
jplara

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

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

Правка эту часть

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

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

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
Cesar

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

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>
0
Eamorr

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

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

        }
    });
0
CJ Madolara