web-dev-qa-db-ja.com

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

上記のコードは正確には機能しませんが、グリッドへのスナップ機能は機能しません。

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

1つのオプションは、1のステップサイズを使用して、選択した値を含む配列を参照することです。 0から始めて20まで進み、array [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/

6
Broshi

誰かがこれをjQuery Webサイトに投稿しました。見る:

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

そして

http://jsbin.com/ezema

それはまさにあなたが持っているものですが、はるかに簡単です(1行のコードのように)。

4
Addo Solutions

ここに私がやった方法があります。デモはこちら- 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")]);
    }
});
3
jplara

カスタム(一貫性のない「ステップ」サイズ)デュアルスライダー(アイデアが明確になった場合はシングルスライダーに変更できます)の簡単なソリューションを次に示します。スライダーの名前は「スライダーユーロ」、テキストエリアはコードでわかるように、名前付き量ユーロ。アイデアは、0から100までのスライダーと101の場所を持つ配列( "realvalues")を持つことです。スライダー値は、その配列内の場所として理解されます。唯一のことは、スライダーの値を取得するときに配列を参照する必要があることです。これが私の例です:

    $(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

上記の@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>
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