【问题标题】:Determine the movement range of the "thumb" on a range input在范围输入上确定“拇指”的移动范围
【发布时间】:2017-01-09 14:08:25
【问题描述】:

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

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

我如何考虑到这一点?

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

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

var off = myRange.clientWidth / (parseInt(myRange.max) - parseInt(myRange.min));
var px = ((myRange.valueAsNumber - parseInt(myRange.min)) * off) - (myValue.clientWidth / 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);
  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>

【问题讨论】:

  • 您能否将相关代码发布到问题中,如果可能,请添加 jsFiddle、Plunkr 或类似的代码来演示问题。
  • 不要迂腐,但我认为我的描述和提供的图像应该最清楚地说明我的方法和手头的问题。
  • 你不是书呆子 :) 图像不允许我们帮助你,因为我们看不到你的代码,也不知道你的 CSS、HTML 或脚本(如果相关)做了什么,任何事情都对猜测。此外,如果图像由于某种原因被删除或更改,则该问题对任何未来有类似问题的用户都没有用。最后,您希望我们为您提供帮助的难易程度取决于您。
  • @RoyPrins 老兄,你发现courellation了吗?它该死的不清楚它是如何移动的
  • 我只有最模糊的记忆,甚至问过这个问题,我当时肯定没有解决它。我没有时间,但只是为了它,我会为这个问题添加一个赏金。蜂蜜会吸引苍蝇,对吧:)

标签: javascript html css input range


【解决方案1】:

使用 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>

【讨论】:

  • 谢谢,看起来很棒。如果允许,我会给你奖励。
【解决方案2】:

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

为了在定位值显示时考虑到这一点,我们需要将其偏移拇指宽度一半的百分比,范围从 +7.5px 到 -7.5px。这是一个更新的小提琴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>

【讨论】:

    【解决方案3】:

    其实你可以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 从 &lt;input type="range"&gt; 中读取拇指的宽度,这样就不需要自定义 CSS。但是reach it inside the user agent shadow dom似乎是不可能的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多