跳到正文

级联选择

多级联动选择(省市区、分类树)。数据写成页面里的嵌套列表,或用 ZhaoUI.cascader 传一棵树。支持搜索、悬停展开,窄屏自动变成逐级下钻。

带行为 分包 modular/select 1 个事件 3 个方法

示例

在线试用 Markdown 版

代码

<div data-zh-cascader data-name="region" data-searchable data-value="浙江/杭州/西湖区" data-placeholder="请选择地区" aria-label="地区">
  <ul hidden>
    <li>浙江
      <ul>
        <li>杭州<ul><li>西湖区</li><li>余杭区</li></ul></li>
        <li>宁波<ul><li>海曙区</li><li>鄞州区</li></ul></li>
      </ul>
    </li>
    <li>江苏<ul><li>南京<ul><li>玄武区</li></ul></li></ul></li>
    <li data-disabled>海南<ul><li>海口<ul><li>龙华区</li></ul></li></ul></li>
  </ul>
</div>

<div id="cas2"></div>

<script>
document.querySelector('[data-zh-cascader]').addEventListener('zh:cascader-change', function (e) {
  console.log(e.detail.text);   // 浙江 / 杭州 / 西湖区
});

ZhaoUI.cascader('#cas2', {
  expandTrigger: 'hover',
  data: [{ label: '前端', value: 'fe', children: [{ label: 'Vue', value: 'vue' }, { label: 'React', value: 'react' }] }],
  onChange: function (labels, text, nodes) { console.log(nodes.map(function (n) { return n.value; })); }
});
</script>

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

属性

属性用在取值说明
data-zh-cascader容器 <div>无声明这是一个级联选择;容器里的第一个 <ul> 是数据,读取后会被替换成控件
data-name容器字段名生成一个隐藏 <input name=…> 参与表单提交,值是用 / 连接的路径(如 浙江/杭州/西湖区);如果路径上每个节点都写了 data-value,则用 data-value 连接
data-value容器用 / 连接的标签路径,如 浙江/杭州/西湖区初始选中的路径;标签里含有 / 时请改用命令式
data-placeholder容器字符串占位文字,默认「请选择」
data-searchable容器布尔属性可输入搜索,匹配完整路径文字,只搜到叶子节点
data-clearable容器false 表示关闭默认有清除按钮
data-expand-trigger容器click(默认)| hover悬停展开下一级;触屏和窄屏始终是点击
data-size容器sm | md(默认)| lg尺寸
data-sep容器字符串,默认「 / 」输入框里各级之间的分隔文字
data-labelledby容器标签元素的 id无障碍名称;也可以直接写 aria-label
data-disabled / data-value<li>布尔属性 / 字符串禁用该节点及其子树 / 该节点的值(用于表单)
<label for="容器 id">容器所在页面的 <label>for 指向容器的 idlabel 会成为输入框的无障碍名称,点击 label 会聚焦输入框;容器是空 <div>,label 的 for 指向它的 id 即可

事件

事件触发于detail说明
zh:cascader-change容器{ path, text, nodes }选中或清除后触发(冒泡)。path 是标签数组,text 是拼好的文字,nodes 是节点对象数组(能读到你自己加的字段,如 value);清除时都是空的

方法

  • ZhaoUI.cascader(host, { data, value, searchable, clearable, expandTrigger, size, placeholder, sep, labelledby, onChange }):命令式创建。data 是节点树 [{ label, children?, disabled?, …你的字段 }];value 是标签数组;onChange(labels, text, nodes)
  • el.zhCascader.get() / .getNodes():读取当前路径的标签数组 / 节点对象数组
  • el.zhCascader.set(labels) / .setData(tree) / .open() / .close():设置路径(不触发 change,并同步隐藏字段)、更换数据、打开、关闭

样式类

zh-sel zh-cas-panel zh-cas-col zh-cas-item

无障碍

  • 输入框是 role="combobox",各级是 role="listbox",带 aria-selected 与 aria-activedescendant
  • ↓ ↑ 在当前一级移动(跳过禁用项),→ 展开子级,← 回到上一级,Enter 选中叶子或展开分支,Esc / Tab 关闭
  • 搜索时 ↓ ↑ 在结果里移动,Enter 选中;结果显示完整路径
  • 窄屏(≤ 767px)改为逐级下钻,有「返回上一级」按钮,每一级都是整行的大点击区
  • 禁用的节点标记 aria-disabled,不可展开也不可选

常见问题

级联选择是什么?

多级联动选择(省市区、分类树)。数据写成页面里的嵌套列表,或用 ZhaoUI.cascader 传一棵树。支持搜索、悬停展开,窄屏自动变成逐级下钻。

怎么使用级联选择?

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

级联选择有哪些事件?

zh:cascader-change(选中或清除后触发(冒泡)。path 是标签数组,text 是拼好的文字,nodes 是节点对象数组(能读到你自己加的字段,如 value);清除时都是空的)。

级联选择有哪些方法?

ZhaoUI.cascader(host, { data, value, searchable, clearable, expandTrigger, size, placeholder, sep, labelledby, onChange }):命令式创建。data 是节点树 [{ label, children?, disabled?, …你的字段 }];value 是标签数组;onChange(labels, text, nodes);el.zhCascader.get() / .getNodes():读取当前路径的标签数组 / 节点对象数组;el.zhCascader.set(labels) / .setData(tree) / .open() / .close():设置路径(不触发 change,并同步隐藏字段)、更换数据、打开、关闭。

级联选择支持键盘和读屏吗?

输入框是 role="combobox",各级是 role="listbox",带 aria-selected 与 aria-activedescendant;↓ ↑ 在当前一级移动(跳过禁用项),→ 展开子级,← 回到上一级,Enter 选中叶子或展开分支,Esc / Tab 关闭;搜索时 ↓ ↑ 在结果里移动,Enter 选中;结果显示完整路径。

级联选择需要依赖框架吗?

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