Я пытаюсь отобразить значение элемента диапазона с центром над большим пальцем. Это работает довольно хорошо, считывая значение и помещая элемент над элементом диапазона в процентах от его clientWidth.

Однако существует растущее смещение от середины (см. Рисунки), что приводит к тому, что значение не центрируется на большом пальце. Я убежден, что это вызвано тем, что большой палец на самом деле перемещается меньше, чем clientWidth из-за размера самого большого пальца и, возможно, некоторого пространства вокруг дорожки.

Как мне это учесть?

Correct positioning in the center

Offset to the left

And to the right

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>
3
Roy Prins 9 Янв 2017 в 17:08

2 ответа

Лучший ответ

Проверьте это для более с помощью CSS: ссылка

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
Aashif Ahamed 7 Фев 2020 в 11:14

Я думаю, что я решил это. Проблема была вызвана тем, что ширина большого пальца не учитывалась. Большой палец не перемещается по ползунку 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>
1
spirift 7 Фев 2020 в 11:05