【问题标题】:JQuery Slider, how to make "step" size changeJQuery Slider,如何改变“步长”大小
【发布时间】:2010-11-01 07:53:25
【问题描述】:

是否可以使用 JQuery Slider(范围滑块/双滑块)来获得非线性(不一致的“步长”大小)值?

我想让水平 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;
}

上面的代码不完全有效,但对齐网格功能不起作用。

【问题讨论】:

    标签: javascript jquery html user-interface slider


    【解决方案1】:

    除了上面@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>
    

    【讨论】:

      【解决方案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]);
               }
           });
          });
      

      【讨论】:

      • 除了“valMap”中的数组值,您还可以使用来自 json 的输入
      【解决方案3】:

      我想我可以提供一个更好的解决方案: 我们的想法是将一个包含我的真实值的数组与滑块分开,然后将 step 属性始终设置为 1 并让滑块与该数组的 index 一起工作,然后从我的真实数据中获取实际值大批。希望这个例子有帮助:http://jsfiddle.net/3B3tt/3/

      【讨论】:

      • 这是此页面 AFAIC 上的最佳解决方案。干得好。
      • 嘿@Eamorr,谢谢;-)
      • 如果您不想要步骤之间的间隙,这绝对是最好的解决方案。
      【解决方案4】:

      只需更改值。

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

      【讨论】:

        【解决方案5】:

        这就是我的做法。 演示在这里 - 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")]);
            }
        });
        

        【讨论】:

          【解决方案6】:

          我不得不做类似的事情,即使这是一个较晚的响应,其他人可能会像我一样在这个线程上发生,并且发现我的解决方案很有用。这是我创建的解决方案:

          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.
          

          【讨论】:

            【解决方案7】:

            这是我对自定义(不一致的“步长”大小)双滑块的简单解决方案(如果想法变得清晰,您可以将其修改为单滑块) 我的滑块名为“slider-euro”,文本区域名为 amount-euro,如您在代码中所见。 这个想法是有一个从 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 )]+" €" );
                });
            

            【讨论】:

              【解决方案8】:

              有人在 jQuery 网站上发布了这个。见:

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

              http://jsbin.com/ezema

              这正是你所拥有的,但更简单(如 1 行代码)。

              【讨论】:

                【解决方案9】:

                如果最小值和最大值相同,则滑块值不变

                改变这部分

                        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】:

                  不确定您是否希望滑块比例与您的值成比例*,但如果是这样,我为其他提出相同问题的人提供了解决方案。 You can find my solution here。基本上,我使用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 数组(代表滑块停止点)中的数字,直到按照您想要的方式将它们隔开。这样,从用户的角度来看,您可以让它感觉就像它与值成比例地滑动,但又不会被夸大。显然,如果您的真实值是动态创建的,您可能需要提出一种算法来生成滑块值,而不是静态定义它们...

                  【讨论】:

                  • @Alconja - 您的底部示例看起来很棒,但是,如果我使用双手柄(滑块范围),我认为它不起作用。这是正确的,如果是这样 - 我将如何修改您的代码以使其工作?非常感谢
                  • @Alconja - 另外,这是否适用于“对齐网格”功能?看起来不是这样。
                  • @TomHankers - “对齐网格”应该可以工作(当我构建另一个示例时),并且不,它目前不适用于双手柄,但我会看看给你的……
                  • @Alconja - 感谢您查看双手柄。我的代码在原帖上面。
                  • @Alconja - 哇,谢谢你的脚本。是的,你是对的 - 前几个值数组 # 无法选择 b/c 它们太小了。是否可以反转值之间的距离,以便接近值之间的距离更大,值之间的大差异之间的距离更小? (所以滑块上 0-500 之间的距离大于 500,000-1,000,000 之间的距离
                  【解决方案11】:

                  您的一个选项是使用 1 的步长并引用包含您选择的值的数组。从 0 开始,一直到 20,获取 array[value_of_slider] 以获取您的实际值。我不太了解滑块,无法告诉您是否有办法为其提供一组自定义值。

                  【讨论】:

                  • @Seburdis - “引用包含您选择的文件的数组。”什么文件?查看可用的演示
                  • 即有一个数组 values_array=[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 150, 200, 250, 500, 1000, 1500 , 2000, 2500, 5000, 10000]。滑块的最小值为 0,最大值为 20。准备显示值时,使用 values_array[slider.value]。
                  • @Chuck,你介意发布代码来实现它吗?
                  • @TomHankers - 我的错,我在考虑值和类型的文件。现已修复。
                  【解决方案12】:

                  基于@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});
                  

                  【讨论】:

                  • @karim79 - 很棒的小脚本;但是,如何让它与 Range Slider(双滑块)一起使用?
                  • @karim79 - 仍然很想知道如何让它与双手柄范围滑块一起工作:)
                  • 你可能错了,应该是这个 --> max:prices_array.length - 1 和这个 prices_arrayprices_arr
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2020-01-19
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2023-04-01
                  • 2020-01-31
                  相关资源
                  最近更新 更多