跳到正文

下拉选择

增强原生 <select>:单选、多选、搜索、分组、清除、选项描述,选中值同步回原生 select 并触发原生 change,表单提交、name、required 照常工作。也可用 ZhaoUI.select 命令式创建,支持远程搜索和自动完成。

带行为 分包 modular/select 2 个事件 4 个方法

示例

在线试用 Markdown 版

代码

<label for="region">区域</label>
<select id="region" name="region" data-zh-select data-clearable required>
  <option value="">请选择区域</option>
  <option value="east">华东</option>
  <option value="south">华南</option>
  <option value="north">华北</option>
</select>

<label for="city">城市</label>
<select id="city" name="city" data-zh-select data-searchable data-empty-text="没有这个城市">
  <option value="">请选择城市</option>
  <optgroup label="直辖市">
    <option value="bj" data-keys="beijing bj" data-desc="首都">北京</option>
    <option value="sh" data-keys="shanghai sh">上海</option>
  </optgroup>
  <optgroup label="广东省">
    <option value="gz" data-keys="guangzhou gz">广州</option>
    <option value="sz" data-keys="shenzhen sz" disabled>深圳</option>
  </optgroup>
</select>

<label for="tags">标签</label>
<select id="tags" name="tags" multiple data-zh-select data-searchable data-clearable data-max-tags="2">
  <option value="fe" selected>前端</option>
  <option value="be" selected>后端</option>
  <option value="ux">设计</option>
</select>

<div id="remote"></div>

<script>
document.getElementById('region').addEventListener('change', function (e) {
  console.log(e.target.value);
});

// 远程搜索
ZhaoUI.select('#remote', {
  searchable: true, clearable: true, placeholder: '搜索技术',
  source: function (q) {
    return fetch('/api/tech?q=' + encodeURIComponent(q)).then(function (r) { return r.json(); });   // 返回 [{ value, label }, …]
  }
});
</script>

只用核心包(modular/core)时,还要加 modular/select.min.js 和 modular/select.min.css;全量版已包含。见 按需引入。

属性

属性用在取值说明
data-zh-select<select>无声明要增强这个 select;选项、optgroup、disabled、multiple、selected 都从它读取
multiple<select>布尔属性多选:选中项显示为标签,列表保持打开
data-searchable<select>布尔属性可输入搜索;按选项文字、data-desc、data-keys 匹配并高亮
data-clearable<select>布尔属性有值时显示清除按钮
data-size<select>sm | md(默认)| lg尺寸
data-placeholder<select>字符串占位文字;不写则取值为空的那个 <option> 的文字,再没有则是「请选择」
data-empty-text<select>字符串搜索无结果时的提示,默认「无匹配项」
data-max-tags<select multiple>整数最多显示几个标签,其余折叠为「+N」
data-prefix-icon<select>图标名输入框前的图标
data-desc / data-icon / data-keys<option>字符串选项的第二行说明 / 图标 / 额外的搜索关键词(如拼音)
value=""<option>空值放一个空值的 option 作为占位;它不会出现在选项列表里,清除后 select 会回到它
aria-invalid="true"<select>true错误状态外观

事件

事件触发于detail说明
change / input原生 <select>原生事件选中值变化时在原生 select 上触发(冒泡),已有的表单代码不用改
zh:select-change生成的控件(select 后面的 .zh-sel){ value, labels }单选时 value 是字符串,多选时是数组;labels 是对应的文字数组

方法

  • selectEl.zhSelect.get() / .set(value):读取或设置值(多选传数组)。set 会同步原生 select,但不触发 change
  • selectEl.zhSelect.setOptions([{ value, label, desc?, icon?, disabled? }, …]):更换选项(支持分组:{ label, options: [...] })。原生 <select> 里的 <option> 会一起重建,已选且仍存在的值会保留,不再存在的会被移除
  • selectEl.zhSelect.setDisabled(bool) / .setInvalid(bool) / .open() / .close():禁用、错误状态、打开、关闭
  • ZhaoUI.select(host, config):命令式创建。host 是一个空 <div> 或选择器;config:options、value、multiple、searchable、clearable、size、placeholder、emptyText、maxTags、prefixIcon、disabled、invalid、labelledby、onChange(value, labels)。 远程搜索:source(query) 返回 Promise<选项数组>,可配 debounce(毫秒,默认 250)和 loading。 自动完成:freeText: true,输入的文字本身就是值,chevron: false 可隐藏箭头。返回同一套方法(get / set / setOptions / setDisabled / setInvalid / open / close)

样式类

zh-sel zh-sel-native

无障碍

  • 输入框是 role="combobox",带 aria-expanded / aria-controls / aria-activedescendant;列表是 role="listbox",选项是 role="option",多选时有 aria-multiselectable
  • <label for> 指向原生 select 时,点击 label 或表单校验聚焦,都会转到可见的输入框
  • ↓ ↑ 打开并移动(到头会循环),Home / End 到首尾,Enter 选中,Esc 关闭,Tab 关闭并继续;不可搜索时直接输入字母可跳到对应选项,空格打开
  • 多选时在空输入上按退格删除最后一个标签;标签上有带 aria-label 的移除按钮
  • 禁用的选项标记 aria-disabled,不可选中,方向键会跳过
  • 原生 select 保留在表单里(视觉隐藏、aria-hidden、不可 Tab),所以 required 的浏览器校验仍然有效

常见问题

下拉选择是什么?

增强原生 <select>:单选、多选、搜索、分组、清除、选项描述,选中值同步回原生 select 并触发原生 change,表单提交、name、required 照常工作。也可用 ZhaoUI.select 命令式创建,支持远程搜索和自动完成。

怎么使用下拉选择?

先在页面里引入 zhaoui.css 和 zhaoui.js(放在 </body> 前,不加 defer),再照本页「用法」里的标记书写;需要用代码控制时,用「方法」里列出的接口。

下拉选择有哪些事件?

change / input(选中值变化时在原生 select 上触发(冒泡),已有的表单代码不用改);zh:select-change(单选时 value 是字符串,多选时是数组;labels 是对应的文字数组)。

下拉选择有哪些方法?

selectEl.zhSelect.get() / .set(value):读取或设置值(多选传数组)。set 会同步原生 select,但不触发 change;selectEl.zhSelect.setOptions([{ value, label, desc?, icon?, disabled? }, …]):更换选项(支持分组:{ label, options: [...] })。原生 <select> 里的 <option> 会一起重建,已选且仍存在的值会保留,不再存在的会被移除;selectEl.zhSelect.setDisabled(bool) / .setInvalid(bool) / .open() / .close():禁用、错误状态、打开、关闭;ZhaoUI.select(host, config):命令式创建。host 是一个空 <div> 或选择器;config:options、value、multiple、searchable、clearable、size、placeholder、emptyText、maxTags、prefixIcon、disabled、invalid、labelledby、onChange(value, labels)。 远程搜索:source(query) 返回 Promise<选项数组>,可配 debounce(毫秒,默认 250)和 loading。 自动完成:freeText: true,输入的文字本身就是值,chevron: false 可隐藏箭头。返回同一套方法(get / set / setOptions / setDisabled / setInvalid / open / close)。

下拉选择支持键盘和读屏吗?

输入框是 role="combobox",带 aria-expanded / aria-controls / aria-activedescendant;列表是 role="listbox",选项是 role="option",多选时有 aria-multiselectable;<label for> 指向原生 select 时,点击 label 或表单校验聚焦,都会转到可见的输入框;↓ ↑ 打开并移动(到头会循环),Home / End 到首尾,Enter 选中,Esc 关闭,Tab 关闭并继续;不可搜索时直接输入字母可跳到对应选项,空格打开。

下拉选择需要依赖框架吗?

不需要。ZhaoUI 是原生 HTML、CSS 和 JavaScript,不依赖 jQuery、Vue 或 React。