2009-06-08 2 views
61

Можно ли использовать ползунок JQuery (ползунок/двойной слайдер) для нелинейного (непоследовательного) размера шага?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; 
} 

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

ответ

50

Не уверен, что если вы хотите, чтобы масштаб ползунка быть в пропорции к вашим ценностям *, но если это так, Я предоставил решение для этого другого, кто задал тот же вопрос. You can find my solution here. В основном я использую событие slide, которое запускается, когда вы перемещаете ползунок, чтобы имитировать степпинг, но основываясь на настраиваемом массиве, определяющем этапы. Таким образом, он позволяет вам «переходить» к вашим предопределенным значениям, даже если они не распределены равномерно.

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

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

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

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

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


Edit: Ok, эта версия сценария должна работать с двумя ползунками:

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

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


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

+1

@Alconja - Ваш нижний пример выглядит отлично, но я не верю, что он работает, если я использую двойную ручку (диапазон ползунков). Правильно ли, если да, как бы я изменил ваш код, чтобы сделать эту работу? Большое спасибо –

+0

@Alconja - Также, это работает с функциональностью «привязка к сетке»? Это не так. –

+0

@TomHankers - «привязка к сетке» должна работать (это было, когда я построил другой пример), и в настоящее время он не работает с двумя ручками, но я посмотрю на это для вас ... – Alconja

7

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

+0

@Seburdis - "ссылаться на массив, содержащий выбранные файлы." какие файлы? См. Демонстрационную версию –

+0

То есть, имеют значения array_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

+0

@ Чак, не возражаете ли вы опубликовать код, который сделает эту работу. –

6

Исходя из вышеизложенного ответа и обсуждения с @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}); 
+0

@ karim79 - большой скрипт; однако, как мне заставить это работать с ползунком диапазона (двойной слайдер)? –

+0

@ karim79 - все еще любопытно узнать, как заставить это работать с ползунком с двумя дескрипторами: –

+0

вы, возможно, ошибаетесь в этом, и должно быть это -> 'max: prices_array.length - 1', и этот' price_array' для 'prices_arr' –

1

Если значения 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); 
      } 
     } 
2

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

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

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. 
2

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

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

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

спасибо kleopatra за форматирование! –

5

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

+2

Это лучшее решение на этой странице AFAIC. Хорошая работа. – Eamorr

+0

Hey @Eamorr, Thanks ;-) – Broshi

+1

Это, безусловно, лучшее решение, если вы не хотите даже пробелов между шагами. – daSong

9

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

Вместо значений массива в «valMap» вы также можете использовать ввод от json –

0

Далее в @ 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> 
Смежные вопросы