## 35 · 滑动选择器 Slider ### 35.1 用途 在一个连续区间里用一次滑动选出数值(预算上限、价格区间、音量、亮度);移动端与桌面端的关键差别是**热区**:轨道可视高度只有 4px,但整条轨道所在的行必须是 44px 高的热区,且按下任意位置就要跳到该处 —— 触屏上要求用户精确抓住 20px 的滑块是点不中的。 ### 35.2 结构(anatomy) - `slider`:根元素,一行里放进「轨道热区 + 数值」 - `rail`:轨道热区,44px 高的可聚焦区域,承载指针事件与锚点 - `track`:轨道本体(可视 4px),承载选中段与刻度的边界 - `filled`:选中段,从起点铺到滑块位置 - `thumb`:滑块,位置由当前值的百分比决定;拖动中放大作为「抓住了」的反馈 - `mark`:刻度点,仅 `marks=with-marks` 时出现(只标位置,不写文案) ### 35.3 变体维度 - `mode`:`single`(单滑块)/ `range`(双滑块,左值不越过右值) - `marks`:`with-marks`(轨道上标出等分点)/ `none`(不标刻度) - `showValue`:`true`(右侧显示当前值)/ `false`(不显示数值) ### 35.4 状态 - default:常态 - dragging:拖动中(滑块 20px → 24px,轨道加一层浅底) - disabled:整条置灰且不响应,指针与键盘都不改值 ### 35.5 交互与触控 - 轨道热区高 44px,**按下任意位置即跳到该处**,随后横向拖动连续改值;不要求抓住滑块 - 手势是「按下 + 拖动」一次连续动作,不响应长按或双击;横向分量优先,纵向滚动不被吞掉(`touch-action: pan-y`) - 取值按 `step` 吸附并夹在 `[min, max]`;`mode=range` 时左值不越过右值、右值不越过左值 - 拖动期间滑块放大到 24px,松手后 150ms 回弹;减少动态偏好下瞬时切换 - 值变化立即触发 change 事件(连续回传),不做防抖;松手时才做业务提交 ### 35.6 无障碍 - 单滑块:轨道热区是 `role="slider"` 且可聚焦,写 `aria-valuemin` / `aria-valuemax` / `aria-valuenow` / `aria-label` - 双滑块:外层是 `role="group"` + `aria-label`,每个滑块各自持有 `aria-valuenow`(两条独立数值) - 禁用时写 `aria-disabled="true"`,读屏会播报不可用 - 键盘:聚焦后左右方向键按 `step` 步进(触屏之外的替代路径) ### 35.7 doNotInvent - 数值输入框与滑块的双向绑定(宿主自行组合 Input,本组件只回传值) - 刻度上的文案标注与区间高亮(只标位置,不写文案) - 拖动结束后的「撤销 / 重置」流程 - 纵向滑块与圆形表盘式选择器 ### 35.8 unknowns - 双滑块的最小间距是否应当是 1 个 step(当前是),还是用户可配 - 刻度数量是否应由 `step` 推导(当前按 5 等分固定标点) - 拖动中是否要把当前值放大显示在滑块上方(气泡提示) ---