#javascript #html #css
Вопрос:
Это очень специфично и отчасти случайно, и ответы, которые я нашел, не совсем соответствуют этому конкретному варианту использования. Для краткости, вот ссылка на демо-версию CodePen:
https://codepen.io/mikejandreau/pen/GRWNprN
Как вы, вероятно, можете видеть с первого взгляда, у меня есть четыре метки данных, которые не совпадают с ползунком диапазона при его перемещении. Минимальные и максимальные значения в порядке, у меня проблемы только со средними значениями.
Это основано на примере, в котором были только минимальные/максимальные значения, и я пытаюсь его настроить. Я попытался добавить дополнительные атрибуты данных между data-min-label-id
и data-max-label-id
, хотя это не сработало так хорошо.
Как обычно, я, вероятно, упускаю что-то очевидное. Мы будем очень признательны за любую помощь или указания.
<div id="wrapper">
<div id="sliderContainer">
<div class="tick-slider">
<div class="tick-slider-header">
<span><label for="weightSlider">Slider</label></span>
</div>
<div class="tick-slider-background"></div>
<div id="weightProgress" class="tick-slider-progress"></div>
<div id="weightTicks" class="tick-slider-tick-container"></div>
<input
id="weightSlider"
class="tick-slider-input"
type="range"
min="0"
max="5000"
step="1000"
value="1000"
data-tick-step="1000"
data-tick-id="weightTicks"
data-value-id="weightValue"
data-progress-id="weightProgress"
data-handle-size="18"
data-min-label-id="weightLabelMin"
data-max-label-id="weightLabelMax"
/>
<div class="tick-slider-value-container">
<div id="weightLabelMin" class="tick-slider-label">0</div>
<!-- I want to align these 4 items -->
<div id="weightLabelA" class="tick-slider-label">1000</div>
<div id="weightLabelB" class="tick-slider-label">2000</div>
<div id="weightLabelC" class="tick-slider-label">3000</div>
<div id="weightLabelD" class="tick-slider-label">4000</div>
<div id="weightLabelMax" class="tick-slider-label">5000</div>
<div id="weightValue" class="tick-slider-value"></div>
</div>
</div>
</div>
function init() {
const sliders = document.getElementsByClassName("tick-slider-input");
for (let slider of sliders) {
slider.oninput = onSliderInput;
updateValue(slider);
updateValuePosition(slider);
updateLabels(slider);
updateProgress(slider);
setTicks(slider);
}
}
function onSliderInput(event) {
updateValue(event.target);
updateValuePosition(event.target);
updateLabels(event.target);
updateProgress(event.target);
}
function updateValue(slider) {
let value = document.getElementById(slider.dataset.valueId);
value.innerHTML = "<div>" slider.value "</div>";
}
function updateValuePosition(slider) {
let value = document.getElementById(slider.dataset.valueId);
const percent = getSliderPercent(slider);
const sliderWidth = slider.getBoundingClientRect().width;
const valueWidth = value.getBoundingClientRect().width;
const handleSize = slider.dataset.handleSize;
let left = percent * (sliderWidth - handleSize) handleSize / 2 - valueWidth / 2;
left = Math.min(left, sliderWidth - valueWidth);
left = slider.value === slider.min ? 0 : left;
value.style.left = left "px";
}
function updateLabels(slider) {
const value = document.getElementById(slider.dataset.valueId);
const minLabel = document.getElementById(slider.dataset.minLabelId);
const maxLabel = document.getElementById(slider.dataset.maxLabelId);
const valueRect = value.getBoundingClientRect();
const minLabelRect = minLabel.getBoundingClientRect();
const maxLabelRect = maxLabel.getBoundingClientRect();
const minLabelDelta = valueRect.left - (minLabelRect.left);
const maxLabelDelta = maxLabelRect.left - valueRect.left;
const deltaThreshold = 32;
if (minLabelDelta < deltaThreshold) minLabel.classList.add("hidden");
else minLabel.classList.remove("hidden");
if (maxLabelDelta < deltaThreshold) maxLabel.classList.add("hidden");
else maxLabel.classList.remove("hidden");
}
function updateProgress(slider) {
let progress = document.getElementById(slider.dataset.progressId);
const percent = getSliderPercent(slider);
progress.style.width = percent * 100 "%";
}
function getSliderPercent(slider) {
const range = slider.max - slider.min;
const absValue = slider.value - slider.min;
return absValue / range;
}
function setTicks(slider) {
let container = document.getElementById(slider.dataset.tickId);
const spacing = parseFloat(slider.dataset.tickStep);
const sliderRange = slider.max - slider.min;
const tickCount = sliderRange / spacing 1; // 1 to account for 0
for (let ii = 0; ii < tickCount; ii ) {
let tick = document.createElement("span");
tick.className = "tick-slider-tick";
container.appendChild(tick);
}
}
function onResize() {
const sliders = document.getElementsByClassName("tick-slider-input");
for (let slider of sliders) {
updateValuePosition(slider);
}
}
window.onload = init;
window.addEventListener("resize", onResize);