javascript - 如何在最小值和最大值之间对齐范围滑块中的数据标签
问题描述
这是非常具体和随机的,我发现的答案不太适合这个特定的用例。为简洁起见,这里是 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);
解决方案
推荐阅读
- r - R中的直方图
- java - Spring Boot 应用程序无法热交换更改
- django - Django Admin Automation 向管理员发送每日查询活动
- c# - 使用 WixSharp 如何在卸载时执行的自定义操作期间获取正确的 InstallDir 路径
- sql - 选择具有 X 最高值的列名
- javascript - 未捕获的错误:模板解析错误:无法绑定到“配置文件”,因为它不是“app-trnmnt-name”的已知属性
- fortran - Fortran 格式 - 数字 < 1e-100 的问题
- c# - 访问来自父用户控件的绑定变量
- ios - iOS 12 的 AVPlayerViewController 问题
- java - 尝试读取 CSV 文件时使用 Selenium Web Driver 运行自动化脚本时出错