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;
}
上記のコードは正確には機能していませんが、グリッドへのスナップ機能は機能しません。
ベストアンサー1
スライダーのスケールを値に比例させたいかどうかはわかりませんが、もしそうなら、同じ質問をした他の人のために解決策を提供しました。私の解決策はここにあります基本的に、スライダーを動かしたときにトリガーされるイベントを利用して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
(スライダーの停止ポイントを表す) を、希望どおりの間隔になるまで調整できます。こうすることで、ユーザーの観点から、値に比例してスライドしているように感じさせることができますが、誇張されることはありません。もちろん、実際の値が動的に作成される場合は、静的に定義するのではなく、スライダー値を生成するアルゴリズムを考案する必要があるかもしれません...