如何防止用户向右拖动HTML输入类型为“range”的元素?

6

我有三个 input type='range' 的输入字段,它们具有不同的最大值,但共享相同的容量。每次更改任何一个输入时,此容量将减少。当容量达到 0 时,我应该防止输入字段向右移动(增加其值),只能向左移动,但我不知道如何使用 JS 和 jQuery 实现。

以下是输入的 HTML 代码:

<input type="range" class="slider" id="woodSlider" min="0" value="0" max="1558">
<input type="range" class="slider" id="ironSlider" min="0" value="0" max="2555">
<input type="range" class="slider" id="stoneSlider" min="0" value="0" max="2451">

这是一个减少容量的代码:

$("input").change(function() {  
    $("#capacityLeft").html(parseInt(holding.capacity) - 
         $("#woodSlider").val() -
         $("#ironSlider").val() -
         $("#stoneSlider").val());
    if(parseInt($("#capacityLeft").html()) <= 0) {
    // TODO: FIND OUT HOW TO STOP THE SLIDERS FROM MOVING
    }
});

2
将每个值的最大值设置为“容量”减去另外两个值的值似乎是一个好的开始。 - Jon
我在 jsfiddle 上有一个可行的解决方案,一旦您分享您已经尝试过/您当前的代码和解释您卡住的地方,我就可以发布它。 - pawel
@vank091 好的,我已经发布了我的解决方案。 - pawel
2个回答

11

好的,你可以使用event.preventDefault()来阻止事件。你应该将一个函数绑定到这些范围滑块的onchangeoninput事件上,并计算总和,检查是否超过最大值,如果是,则停止事件。

这是一个纯JS的解决方案(fiddle 链接),可以很容易地用jQuery重写。

var maxTotal = 150, // define the max sum of values
    inputs = [].slice.call(document.getElementsByTagName('input')), // refrence to the elements
    getTotal = function(){ // helper function to calculate the sum
        var sum = 0;
        inputs.forEach( function(input){
           sum += parseInt(input.value, 10); 
        });
        return sum;
    },
    maxReached = function(e){  // check if the max is reached
        var sum = getTotal(), target;
        if(sum > maxTotal){
            target = e.target;
            // set the max possible value if the user, for example, clicks too far to the right
            target.value = target.value - (sum - maxTotal);
            // next line is just for demonstrational purposes
            document.getElementById('total').innerHTML = getTotal();

            // prevent increasing the value
            e.preventDefault();
            return false;
        }
        // next line is just for demonstrational purposes
        document.getElementById('total').innerHTML = getTotal();

        // everything's fine, nothing to do.
        return true;
    };

// attach the maxReached function to your inputs
inputs.forEach( function(input){
    input.addEventListener('input', maxReached );
});

4
谢谢,关键部分是target.value = target.value - (sum - maxTotal);,它会在滑块的值大于最大值时用最大值来覆盖当前值。我花了一些时间才明白为什么仅使用return false;无法生效。 - nils

0

我瞎搞了一会儿,最终实现了自定义设置输入范围的值(这段代码基本上实现了一个“切换”按钮):

let input = document.getElementById('myInput');
let currentValue = 0;
input.onclick = function(e) {
  currentValue = 1 - currentValue;
  e.target.value = currentValue;
  return false;
}
<input id="myInput" type="range" min="0" max="1" value="0" style="width: 600px;" />

JSFiddle

我使用了onclick,因为我希望每次用户在输入范围内的任何位置点击时都会响应,而不仅仅是根据浏览器的“更改值”来响应。显然,如果您只想在用户更改滑块位置时触发事件,请使用oninputonchange

似乎确实需要手动设置/覆盖e.target.value,因为return false;实际上并没有做任何事情。事实上,即使不返回false,上面的代码也能正常工作


然而,对于移动设备,您需要使用ontouchstart而不是onclick。您还需要return false;以使其正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接