如何限制 jQuery UI 滑块的范围?

How can I restrict the range of a jQuery UI slider?

我创建了一个 jQuery UI 滑块 ,它的 range 设置为 true 并且有两个手柄在 0 和 4。我想将这些手柄的范围限制为最多 4。这意味着当用户滑动其中一个手柄并且另一个手柄的位置使范围超出 4 时,另一个手柄应该滑动以保持范围为 4,但如果范围小于 4,则不应滑动。

这意味着如果 ui.values[0] 等于 0 并且用户滑动另一个手柄说 10,那么这个手柄应该随之滑动到 6。 但是,如果 ui.values[0] 等于 2 并且用户将另一个手柄滑动到 4,那么它应该保持原样。

一些示例值集是:

  1. 1 到 5
  2. 0 到 4
  3. 0 到 2
  4. 16 到 19

我创建了一个 JSFiddle 来尝试这个:https://jsfiddle.net/j4hd760f/

来自 JSFiddle 的代码片段:

$('.slider').slider({
    range: true,
    values: [0, 4],
    slide: function (ev, ui) {
        var ui1 = ui.values[0];
        var ui2 = ui.values[1];
        $('.slider').not(this).each(function () {
            total += $(this).slider('value');
        })
        $('#total').text(ui1 + " " + ui2);
    }
});
.slider {
    margin: 16px;
    width: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<link rel="stylesheet" type="text/css" href="https://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css">
<div id="slider1" class="slider"></div>
<div id="total"></div>

jQuery UI Sliders中没有特定的设置可以直接完成你想要的。因此,您将需要在 slide 处理程序中执行此操作的代码。

下面的代码将完成您想要的。但是,我将最大允许差异更改为 20 而不是 4,因为 4 在 200 像素宽的滑块上是不可见的。您可以通过设置 sliderMaxDifference 轻松更改此最大差异。如果你真的想要 4,另一个片段包含在这个答案的末尾附近。

var sliderMaxDifference = 20;
var timeout;
$('.slider').slider({
    range: true,
    values: [0, 4],
    slide: function (ev, ui) {
        var movedValue = ui.value;
        //ui.handleIndex does not exist in this version of jQuery UI
        //Determine which slider moved
        var handleIndex = 1;
        if(ui.handle.nextSibling && ui.handle.nextSibling.nodeName === 'A'){
            handleIndex = 0;
        }
        var unmovedValue = ui.values[1 - handleIndex];
        //Compute the new value for the unmoved slider
        unmovedValue = Math.max(unmovedValue,movedValue - sliderMaxDifference);
        unmovedValue = Math.min(unmovedValue,movedValue + sliderMaxDifference);
        //Set the following slider value
        $(this).slider('values',1 - handleIndex, unmovedValue);
        //$(this).slider('values') will not yet reflect the new values
        //var newValues=$(this).slider('values');
        var newValues=[]
        newValues[handleIndex] = movedValue;
        newValues[1 - handleIndex] = unmovedValue;
        $('#total').text(newValues[0] + "-->" + newValues[1] 
                         + ' Difference=' + (newValues[1]-newValues[0]));
    }
});
.slider {
    margin: 16px;
    width: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<link rel="stylesheet" type="text/css" href="https://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css">
<div id="slider1" class="slider"></div>
<div id="total"></div>

需要注意的是jQuery UI滑块不允许下滑块大于上滑块。当滑块相等时,这会导致一些 UI 混乱。您必须将最近移动的滑块从另一个滑块移开才能抓住另一个滑块来移动它。

我删除了你的代码:

$('.slider').not(this).each(function () {
    total += $(this).slider('value');
})

因为,它似乎什么都不做(total 从未声明过,或以其他方式使用过)。

如果你真的想要它的差异为 4,那么你可以尝试以下代码片段(仅更改:var sliderMaxDifference = 4;):

var sliderMaxDifference = 4;
var timeout;
$('.slider').slider({
    range: true,
    values: [0, 4],
    slide: function (ev, ui) {
        var movedValue = ui.value;
        //ui.handleIndex does not exist in this version of jQuery UI
        //Determine which slider moved
        var handleIndex = 1;
        if(ui.handle.nextSibling && ui.handle.nextSibling.nodeName === 'A'){
            handleIndex = 0;
        }
        var unmovedValue = ui.values[1 - handleIndex];
        //Compute the new value for the unmoved slider
        unmovedValue = Math.max(unmovedValue,movedValue - sliderMaxDifference);
        unmovedValue = Math.min(unmovedValue,movedValue + sliderMaxDifference);
        //Set the following slider value
        $(this).slider('values',1 - handleIndex, unmovedValue);
        //$(this).slider('values') will not yet reflect the new values
        //var newValues=$(this).slider('values');
        var newValues=[]
        newValues[handleIndex] = movedValue;
        newValues[1 - handleIndex] = unmovedValue;
        $('#total').text(newValues[0] + "-->" + newValues[1] 
                         + ' Difference=' + (newValues[1]-newValues[0]));
    }
});
.slider {
    margin: 16px;
    width: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<link rel="stylesheet" type="text/css" href="https://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css">
<div id="slider1" class="slider"></div>
<div id="total"></div>

更通用的解决方案是使用滑块上的属性来存储该特定滑块允许的差异。

作为 Mayken 回答的补充,在某些时候 jQuery UI 已将滑块手柄元素从 'A' 更改为 'span'。

要使答案在 jQuery 的更新版本中有效,请更改:

if(ui.handle.nextSibling && ui.handle.nextSibling.nodeName === 'A'){

if(ui.handle.nextSibling && ui.handle.nextSibling.nodeName === 'SPAN'){