如何创建输入类型为“范围”的科学 HTML 滑块

问题描述 投票:0回答:3

我需要创建一个科学输入滑块。更准确地说:

  • n 个刻度,例如:无论范围(0 - 200、1 - 11 等),我想要覆盖整个范围的 11 个刻度
  • 每个刻度下方的数值标签
  • 当滑块光标靠近刻度时,没有“胶水”吸引效果

模型:

注:

以下代码生成一个带刻度的 HTML 滑块,并且可以正常工作。但是,它不符合上述第二个和第三个标准。

input { width: 400px; }
<input type=range min=0 max=200 value=0 step=1 list=tickmarks>
<datalist id=tickmarks>
    <option>0</option>
    <option>20</option>
    <option>40</option>
    <option>60</option>
    <option>80</option>
    <option>100</option>
    <option>120</option>
    <option>140</option>
    <option>160</option>
    <option>180</option>
    <option>200</option>
 </datalist>

是否有 HTML

<input type="range">
的属性来启用这些“数字标记”刻度?

满足所有三个标准的实现是否可行?

javascript html css html-input
3个回答
1
投票

您可以通过将 div 放在您划分为多个部分的范围下方来实现此目的。下面的代码只是一个概念验证,它已经可以工作了,但是当你真正将它集成到你的项目中时,你将需要使其可重用和可调整。

window.addEventListener("load", function() {
    let div = document.getElementById("ranger-div");
    let html = [];
    for (let i = 0; i <= 200; i += 20) {
        html.push(`<div><div style="with:100%;">|</div>${i}</div>`);
    }
    div.innerHTML = html.join("");
});
.ranger { width: 400px; }
#ranger-div {display: inline-flex; width: 440px;}
#ranger-div > div {
    color: red;
    width: 100%;
}
<input class="ranger" type=range min=0 max=200 value=0 step=1>
<div id="ranger-div"></div>


1
投票

正如 Lajos Arpad 的回答所示,最好避免使用

datalist
,因为您的要求超出了它的能力范围。您需要手动创建带有数值的刻度。

以下代码使用与您问题中的原始代码相似的 HTML 布局,并具有适合的样式。请注意,宽度是在父元素上设置的,如果父元素太小,则刻度号将换行。为了解决这个问题,您可能需要减小刻度号的字体大小。

#input {
    width: 400px;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
}
#input input {
    width: 100%;
    margin: 0 10px;
    position: relative;
    z-index: 10;
}
#input span {
    position: relative;
    margin: 20px -5px 0 -5px;
    flex-basis: 0;
    flex-grow: 1;
    text-align: center;
    font-size: 0.85em;
    user-select: none;
}
#input span::after {
    content: "";
    position: absolute;
    width: 1px;
    height: 15px;
    left: 0;
    right: 0;
    margin: auto;
    top: -20px;
    background-color: #ccc;
}
<div id="input">
    <input type=range min=0 max=200 value=0 step=1>
    <span>0</span>
    <span>20</span>
    <span>40</span>
    <span>60</span>
    <span>80</span>
    <span>100</span>
    <span>120</span>
    <span>140</span>
    <span>160</span>
    <span>180</span>
    <span>200</span>
</div>


0
投票

您可以使用带有

datalist
列表的
option
,但它需要您添加
label
文本,因为
value
不会用作刻度值。

通用设置MDN:输入类型=“范围”,添加刻度线

    <input type="range" list="tickmark-list">
    <datalist id="tickmark-list">
        <option value=1 label="1"/>
        <option value=N label="N"/>
    </datalist>

对于标签,您有两种选择:

选项 1:使用

label
和文本

<option value="1" label="tickmark-value-1"/>
<option value="N" label="tickmark-value-N"/>

选项2:使用选项文本

<option value="1">tickmark-value-1</option>
<option value="N">tickmark-value-N</option>

同时使用

label
文本和选项文本时,后者将被忽略。对于我使用的片段 option 1.

刻度线

  • input type="range"
    datalist
    必须有相等的
    width
    。在代码片段中,我使用 CSS 自定义属性
    --slider-width: 100%
    来设置任一元素的宽度。
  • datalist
    作为带有
    justify-content: space-between
    的 Flexbox 行容器非常适合分发刻度标签。它将外部标签推到它们各自父级的左右边缘,同时将其余标签均匀分布在剩余空间上。
  • 为了均匀分布刻度标记文本,最好给它们一个等于最大文本的
    width
    。在片段中,我取了标签的宽度
    200
    .
  • 要使标签文本在刻度线下方居中,请使用
    text-align: center
  • 刻度线默认由范围滑块本身插入,不需要任何额外代码。

根据使用的标签文本,可能需要对

margin/padding
和/或
option:first-child
进行一些摆弄。

Bonus

在代码片段中我添加了类 option:last-child 以展示如何使用

.vertical
flex-direction: column
轻松获得 90 度旋转的刻度标签。

writing-mode: vertical-lr
:root  { --slider-width: 100% }

input, datalist  {
    width: var(--slider-width);
}

datalist {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
}

option {
    text-align: center;
    width: 1.78rem; /* ~width of label '200' */
}

.vertical {
    flex-direction: column;
    writing-mode: vertical-lr;
}
input[list="tickmarks2"] { margin: 0 }

.vertical option { text-align: right; width: 1.5rem }

© www.soinside.com 2019 - 2024. All rights reserved.