Skip to content

Slider 滑块 ​

在一段连续范围里拖动选值:音量、透明度这类单个值,或价格、日期这类区间。

单值与范围

value 是数组,滑块数等于它的长度:一个值一个滑块,两个值就是范围(HTML 里写成逗号分隔)。没有可见标签时写 aria-label。

<pt-slider value="50" aria-label="音量"></pt-slider>
<pt-slider value="20,80" aria-label="价格区间"></pt-slider>
取值范围、步长与间隔

min / max / step 决定可取的值,外部给的值按它们夹紧、对齐。min-steps-between-thumbs 让两个滑块至少隔开几步。

<pt-slider value="200,600" min="0" max="1000" step="50" min-steps-between-thumbs="2" aria-label="预算"></pt-slider>
竖向与禁用

orientation="vertical" 时下端是最小值,改宿主的 height 调长度。禁用只淡化已填充的一段、指针变成禁止符号,滑块本身不变。

<pt-slider orientation="vertical" value="60" style="height: 120px" aria-label="竖向"></pt-slider>
<pt-slider orientation="vertical" value="30,70" style="height: 120px" aria-label="竖向范围"></pt-slider>
<pt-slider value="40" disabled aria-label="禁用"></pt-slider>

取值 ​

value 是数字数组,单值也写成数组([50]),滑块数等于数组长度。HTML 里写成逗号分隔的字符串:

html
<!-- 一个滑块 -->
<pt-slider value="50" aria-label="音量"></pt-slider>
<!-- 范围:两个滑块 -->
<pt-slider value="20,80" aria-label="价格区间"></pt-slider>
  • 缺省、null、空串、空数组都按 [min] 处理(一个滑块停在最小值)—— Angular 的 ngModel 初值 null、Vue 的 v-model 初值 undefined 都能直接用。
  • 外部给的值渲染前按 min / max 夹紧、按 step(从 min 起算)对齐、从小到大排序。这份规整只用于显示、读屏和表单提交,不回写 value:使用方赋的值原样保留,直到用户拖动或按键时组件写回一个规整过的新数组并发 ptChange。
  • max 不在步长网格上时(max=10 step=3),最大只能取到不超过它的最后一格(9)。

事件 ​

事件何时触发
ptChange值每变化一次(拖动中持续触发)。v-model / ngModel 绑它
ptCommit一次操作结束且值变了:指针松开,或每一次改变了值的按键

两者的 detail 都是新的数组,都只在用户交互时触发,外部改 value 不发。只在「定下来」时才请求接口的场景监听 ptCommit:

html
<pt-slider value="50" aria-label="音量"></pt-slider>
<script>
  document.querySelector('pt-slider').addEventListener('ptCommit', event => {
    saveVolume(event.detail[0]);
  });
</script>

交互 ​

  • 指针:拖动滑块;点轨道时最近的滑块跳过去,按住不放继续拖。触屏上按住拖动不会滚动页面。
  • 键盘:← ↓ 减一步、→ ↑ 加一步(横向 RTL 下左右对调),PageDown / PageUp 与 Shift + 方向键十步,Home / End 到两端。
  • 多个滑块互不交叉;min-steps-between-thumbs 让相邻两个至少隔开几步(默认 0,可以重叠)。两个滑块重叠时按住拖,往哪边拖就拖动哪一个。
  • 竖向(orientation="vertical")下端是最小值,宿主默认 16px 宽、160px 高,改宿主的 height 即可。

禁用 ​

禁用时已填充的一段淡到 30%、指针变成禁止符号,滑块不可聚焦、不响应任何操作。滑块本身完全不变: 给白色实心的滑块压透明度,深色轨道会从它身体里透出来;换成更淡的描边又会糊进轨道里、看不出滑到了哪儿。

表单 ​

放在 <form> 里按 name 提交,每个滑块一条,同一个名字提交多次:

js
new FormData(form).getAll('price'); // ['20', '80']

表单重置回到初始值;外层 <fieldset disabled> 会禁用它。

无障碍 ​

每个滑块是 role="slider",带 aria-valuenow / aria-valuemin / aria-valuemax / aria-orientation。

  • 一个滑块:aria-label(包装层里是 ariaLabelText)就是它的名字;用 <pt-label for> 关联时标签文字优先。
  • 多个滑块:宿主是 role="group",aria-label(或关联的 pt-label)是整组的名字;各滑块默认念「最小值 / 最大值」(三个及以上按序号), 要换说法用 thumbLabels(只能 JS 赋值)。
  • 读屏默认念数字,要带单位就给 formatValue(只能 JS 赋值),它的返回值写进 aria-valuetext:
js
slider.formatValue = value => `${value} 元`;

定制 ​

通过 ::part() 调整:base、track(轨道)、range(已填充的一段)、thumb(每个滑块)。

API ​

属性

属性Attribute类型默认值说明
ariaLabelTextaria-labelstring | undefined—无障碍名称:原生 HTML 里写 aria-label,React / Vue / Angular 包装层里属性名是 ariaLabelText。 一个滑块时它就是滑块的名字;多个滑块时是整组的名字(各滑块另见 `thumbLabels`)。页面上没有可见标签时必须给。
disableddisabledbooleanfalse禁用:不响应指针与键盘、滑块不可聚焦。只反映使用方自己写的值:外层原生 `<fieldset disabled>`、 pt-field / pt-field-set 的禁用另经继承通道生效,不改写它
formatValue—((value: number, index: number) => string) | undefined—把值格式化成读屏念的文字(`aria-valuetext`),如 `v => v + ' 元'`。只能用 JS 赋值。 缺省不写 aria-valuetext,读屏直接念数字
inheritedDisabledinherited-disabledbooleanfalse外层 pt-field / pt-field-set 下发的禁用。内部继承通道:由它们以 attribute 维护,不建议使用方直接写。 有效禁用是 `disabled` 与它的并集;父元素只写这一条、不碰 `disabled`,读 `el.disabled` 得到的始终是使用方自己写的值
maxmaxnumber100最大值,默认 100。小于 `min` 时按 `min` 处理
minminnumber0最小值,默认 0
minStepsBetweenThumbsmin-steps-between-thumbsnumber0多个滑块时相邻两个之间至少相隔几步(乘以 `step`),默认 0:可以重叠,但不能交叉
namenamestring | undefined—提交表单时的字段名。多个滑块时同一个名字提交多条
orientationorientation"horizontal" | "vertical"'horizontal'方向:horizontal 横向(默认);vertical 竖向,下端是最小值
stepstepnumber1步长,默认 1,从 `min` 起算。`max` 不在步长网格上时,最大只能取到不超过它的最后一格
thumbLabels—string[] | undefined—多个滑块时各自的读屏名字,按序号对应。只能用 JS 赋值。缺省时两个滑块念「最小值 / 最大值」, 三个及以上念「第 n 个值,共 m 个」(走 locale 注册表);只有一个滑块时不用它,名字取 `aria-label`
valuevaluenumber[] | string[]当前值,一个滑块一个数:单值也写成数组(`[50]`),范围写两个(`[20, 80]`)。 数组只能用 JS / 框架绑定赋值;写成 HTML attribute 时用**逗号分隔**(`value="20,80"`,各段去掉首尾空白)。 缺省按 `[min]`。外部赋的值不回写(规整规则见组件说明);用户交互时组件写回一个新数组并发 `ptChange`。

事件

事件detail 类型说明
ptChangenumber[]值在用户交互中每变化一次就触发(拖动中持续触发),detail 是新的 `value`(规整过的数组)。 Vue 的 v-model 与 Angular 的 ngModel 绑在它上面。外部直接改 `value` 不触发。 冒泡(组件默认):滑块不会自我嵌套,冒泡不会串到别的绑定上。
ptCommitnumber[]一次操作结束、且值与操作开始前不同时触发:指针松开,或每一次改变了值的按键。detail 同 `ptChange`。 适合只在「定下来」时才请求接口的场景

方法

方法说明
setFocus(options?: FocusOptions) => Promise<void>聚焦第一个滑块

可定制的内部元素(::part())

part说明
base承载轨道与滑块的容器
range已填充的一段(单个滑块时从起点到滑块,多个时在首末两个滑块之间)
thumb每个滑块
track轨道

Apache-2.0 协议开源