是否可以使用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;
}
上面的代码并不完全正常,但是对齐网格功能不起作用。
答案 0 :(得分:53)
不确定您是否希望滑块刻度与您的值*成比例*但如果是这样,我为其他提出相同问题的人提供了解决方案。 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
数组中的数字(代表滑块停止点),直到你按照你想要的方式间隔它们。通过这种方式,您可以从用户的角度来感受它,就像它与值按比例滑动一样,但不会过于夸张。显然,如果你的真值是动态创建的,你可能需要提出一个算法来生成滑块值而不是静态定义它们......
答案 1 :(得分:14)
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]);
}
});
});
答案 2 :(得分:7)
一个选项是使用步长为1并引用包含所选值的数组。从0开始,最多20,获取数组[value_of_slider]以获得实际值。我不知道滑块是否足以告诉您是否有办法为其提供一组自定义值。
答案 3 :(得分: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});
答案 4 :(得分:5)
我想我可以提供更好的解决方案:
我的想法是使用除滑块之外的实数值保持数组,然后将step
属性始终设置为1并让滑块与该数组的index
一起使用,然后获取实际值来自我的真实数据阵列。希望这个例子有助于:http://jsfiddle.net/3B3tt/3/
答案 5 :(得分:4)
有人在jQuery网站上发布了此消息。参见:
http://forum.jquery.com/topic/non-linear-logarithmic-or-exponential-scale-for-slider
和
这正是你所拥有的,但更简单(如1行代码)。
答案 6 :(得分:3)
这是我如何做到的。 这里演示 - 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")]);
}
});
答案 7 :(得分:2)
这是我对自定义(非一致“步长”尺寸)双滑块的简单解决方案(如果想法变得清晰,您可以将其修改为单滑块) 我的滑块名为“slider-euro”,文本区域的名称为amount-euro,您可以在代码中看到。 我们的想法是有一个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 )]+" €" );
});
答案 8 :(得分:1)
如果最小值和最大值相同,则滑块值不会改变
更改此部分
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);
}
}
答案 9 :(得分:1)
我必须做类似的事情,即使这是一个迟到的回复,其他人可能会像我一样发生在这个线程上,并发现我的解决方案很有用。这是我创建的解决方案:
So apparently, postings containing links to jsfiddle "must be accompanied by code".
OK - here ya go, stackoverflow... Some lovely "code" for you.
答案 10 :(得分: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] );
}
});
答案 11 :(得分:0)
继上面的@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>