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

Posted

技术标签:

【中文标题】如何限制 jQuery UI 滑块的范围?【英文标题】:How can I restrict the range of a jQuery UI slider? 【发布时间】:2017-04-19 03:17:32 【问题描述】:

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

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

一些示例值集是:

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

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

来自 JSFiddle 的代码作为 sn-p:

$('.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>

【问题讨论】:

【参考方案1】:

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

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

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,那么你可以试试下面的sn-p(只改了: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>

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

【讨论】:

【参考方案2】:

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

要在最新版本的 jQuery 中工作的答案,请更改:

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

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

【讨论】:

以上是关于如何限制 jQuery UI 滑块的范围?的主要内容,如果未能解决你的问题,请参考以下文章

将jQuery滑块限制为另一个滑块的值

如何使范围滑块的左侧与滑块右侧的颜色不同?

JQuery UI 范围滑块值

jquery ui滑块-如何反转范围选择

如何在 jquery 滑块中设置最小值和最大值?

如何在 jQuery UI 中创建多范围时间滑块