datalist不满足wcag组合框要求,因其仅是浏览器建议源而非可交互控件:无展开/收起状态反馈、不支持键盘导航闭环、无法监听选中事件、跨浏览器行为不一致,且缺乏必要aria属性与语义结构。

为什么datalist不满足WCAG组合框要求
它只是浏览器提供的建议源,不是可交互控件:没有展开/收起状态反馈,屏幕阅读器读不出“共5条建议”或“已展开”,也不报告当前聚焦项。用户点击<option></option>后值被填入,但你无法监听事件,更没法知道哪条被选中。
常见现象包括:Chrome里能点选,Safari里点了没反应;Firefox只在focus后按向下键才显示;iOS Safari常直接忽略datalist,退化为纯文本框。
最关键的是,它不支持键盘导航闭环——ArrowDown不会聚焦选项,Enter直接提交表单,Escape不收起下拉。
role="combobox"结构必须写的三处ARIA属性
缺一不可,否则键盘和辅助技术都失效:
-
role="combobox":显式声明这是组合框,不是普通输入框 -
aria-expanded="false":实时同步下拉是否展开(JS里必须手动更新) -
aria-controls="suggestions-list":关联下拉容器ID,让屏幕阅读器能定位目标
下拉容器必须是<div role="listbox" id="suggestions-list">,不能用<code><ul></ul>——语义不匹配,会导致焦点管理失败或读屏器跳过。
键盘导航必须拦截的四个按键及其处理逻辑
浏览器不会自动为你实现方向键导航。不接管,ArrowDown会让光标移到输入框末尾,Enter会提交表单,Escape可能只清空输入框而不收起下拉。
实操要点:
- 对
<input>绑定keydown,检测event.key是否为"ArrowDown"/"ArrowUp"/"Enter"/"Escape" - 每次都要调用
event.preventDefault(),否则原生行为照常执行 - 用
querySelectorAll('[role="option"]')获取选项列表,维护一个currentIndex索引 -
ArrowDown时聚焦下一个role="option",到末尾循环回第一个;ArrowUp同理反向循环 -
Enter时取当前聚焦项的dataset.value填入输入框,并触发搜索;Escape时设aria-expanded="false"并隐藏容器
初始DOM结构和焦点管理容易被忽略的细节
下拉容器初始可以display: none,但绝不能从DOM移除——否则aria-controls指向失效,屏幕阅读器找不到目标。
每个role="option"必须设tabindex="-1",否则脚本调用.focus()无效;data-value存实际提交值,文本内容可另加描述(比如带高亮的HTML片段)。
焦点丢失是最大隐患:用户鼠标点选某条建议、或Tab离开再返回,都会让当前焦点脱离下拉结构。必须监听blur和focusout,并在必要时重置currentIndex或强制聚焦第一个选项。











