确定"拇指"的运动范围。在范围输入上

时间:2017-01-09 14:08:25

标签: javascript html css input range

我正在尝试显示以拇指为中心的范围项目的值。通过读取值并将元素定位在范围元素上方作为其clientWidth的百分比,这非常有效。

然而,偏离中间的偏差越来越大(见图片)导致价值不以拇指为中心。我确信这是因为拇指实际上移动的距离小于clientWidth,因为拇指本身的大小可能会在轨道周围有一些空间。

如何将此考虑在内?

Correct positioning in the center

Offset to the left

And to the right

JSFiddle可以在这里找到:https://jsfiddle.net/jd4kncuk/

3 个答案:

答案 0 :(得分:3)

使用CSS进行更多检查: link

var myRange = document.querySelector('#myRange');
var myValue = document.querySelector('#myValue');
var thumbWidth = 18;

var off = (myRange.clientWidth - thumbWidth) / (parseInt(myRange.max) - parseInt(myRange.min));
var px = ((myRange.valueAsNumber - parseInt(myRange.min)) * off) - (myValue.clientWidth / 2) + (thumbWidth / 2);

myValue.style.left = px + 'px';
myValue.style.top = -myRange.offsetHeight - 5 + 'px';
myValue.innerHTML = myRange.value;

myRange.oninput = function() {
  let px = ((myRange.valueAsNumber - parseInt(myRange.min)) * off) - (myValue.clientWidth / 2) + (thumbWidth / 2);
  myValue.innerHTML = myRange.value;
  myValue.style.left = px + 'px';
};
<div style="position:relative; margin:auto; width:90%; margin-top:80px;">
    <output style="position:absolute; min-width:100px; text-align: center;" id="myValue"></output>
    <input type="range" id="myRange" min="0" max="200" step="5" style="width:80%" value="80">
  </div>

答案 1 :(得分:2)

我想我已经解决了。该问题是由于未考虑拇指的宽度引起的。拇指不会在滑块上移动100%,而是100%-〜15px。这样,拇指永远不会与滑块的侧面重叠。请注意,滑块的〜15px宽度是从chrome获取的,在其他浏览器中,宽度可能有所不同。

要在定位值显示时考虑到这一点,我们需要将其偏移拇指宽度的一半,范围为+7.5像素至-7.5像素。这是一个更新的小提琴https://jsfiddle.net/crf96bw7/1/,显示了它的工作原理。我添加了一些额外的标记,以帮助显示值容器的中心位置。

var myRange = document.querySelector('#myRange');
var myValue = document.querySelector('#myValue');
var myValueInner = document.querySelector('#myValueInner');

var buttonWidth = 15;
var range = parseInt(myRange.max) - parseInt(myRange.min)
var centerDotOffset = (myRange.valueAsNumber / range - 0.5) * buttonWidth;
var off = myRange.clientWidth / range;
var px = ((myRange.valueAsNumber - parseInt(myRange.min)) * off) - (myValue.clientWidth / 2) - centerDotOffset;

myValue.style.left = px + 'px';
myValue.style.top = -myRange.offsetHeight - 5 + 'px';
myValueInner.innerHTML = myRange.value;

myRange.oninput = function() {
  var centerDotOffset = (myRange.valueAsNumber / range - 0.5) * buttonWidth
  let px = ((myRange.valueAsNumber - parseInt(myRange.min)) * off) - (myValue.clientWidth / 2) - centerDotOffset;
  myValueInner.innerHTML = myRange.value;
  myValue.style.left = px + 'px';
};
#container {
  position: relative;
  box-sizing: border-box;
  margin: 0 auto;
  width: 90%;
  margin-top: 80px;
}

#myRange {
  width: 100%;
  margin: 0;
}
#myValue {
  background: black;
  
}
#myValue #myValueInner {
  width: 50%;
  background: gold;
}
<div id="container">
  <output style="position:absolute; min-width:100px; text-align: center;" id="myValue"><div id="myValueInner">
  
  </div></output>
  <input type="range" id="myRange" min="0" max="200" step="5" value="150">
</div>

答案 2 :(得分:2)

实际上,您可以style the track and the thumb使用CSS。然后,您具有已知的轨道和拇指宽度(否则,它们取决于平台),然后可以将其合并到计算中。

因此,我在示例中添加了简化的CSS,并将30px的宽度放入thumbWidth JS变量中,并更改了公式:

var myRange = document.querySelector('#myRange');
var myValue = document.querySelector('#myValue');
var thumbWidth = 30;

var off = (myRange.clientWidth - thumbWidth) / (parseInt(myRange.max) - parseInt(myRange.min));
var px = ((myRange.valueAsNumber - parseInt(myRange.min)) * off) - (myValue.clientWidth / 2) + (thumbWidth / 2);

myValue.style.left = px + 'px';
myValue.style.top = -myRange.offsetHeight - 5 + 'px';
myValue.innerHTML = myRange.value;

myRange.oninput = function() {
  let px = ((myRange.valueAsNumber - parseInt(myRange.min)) * off) - (myValue.clientWidth / 2) + (thumbWidth / 2);
  myValue.innerHTML = myRange.value;
  myValue.style.left = px + 'px';
};
input[type=range] {
  -webkit-appearance: none;
  margin: 10px 0;
}
input[type=range]::-webkit-slider-runnable-track {
  height: 10px;
  background: gray;
}
input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none;
  height: 30px;
  width: 30px;
  background: crimson;
  margin-top: -10px;
}
<div style="position:relative; margin:auto; width:90%; margin-top:80px;">
  <output style="position:absolute; min-width:100px; text-align: center;" id="myValue"></output>
  <input type="range" id="myRange" min="0" max="200" step="5" style="width:80%" value="80">
</div>

PS:一种更干净的方法是通过JS从<input type="range">中读取拇指的宽度,这样就不需要自定义CSS。但是,reach it inside the user agent shadow dom似乎不可能。