模态框真正可用需聚焦管理与可访问性:打开时自动聚焦首个可聚焦元素,限制Tab键焦点范围,关闭后恢复原焦点并正确设置ARIA属性。

模态框(Modal)要真正可用,不能只靠显示隐藏和遮罩层——焦点管理与可访问性(a11y)是核心。否则键盘用户无法操作、屏幕阅读器无法理解上下文,甚至可能被困在模态框里出不来。
聚焦进入时自动捕获焦点
模态框打开后,焦点必须立即落在模态内容内首个可聚焦元素上(如关闭按钮或第一个输入框),防止焦点留在背景页面或浏览器地址栏。
- 用 modalElement.focus() 不够——它只对本身可聚焦的元素(如带 tabindex=”-1″ 的 div)有效;更稳妥的是选中内部第一个可聚焦子元素:
const focusable = modal.queryselector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
然后 focusable?.focus() - 打开模态前,保存当前焦点元素(document.activeElement),便于关闭后恢复
限制 Tab 键焦点范围(焦点环)
键盘用户按 Tab 时,焦点不能“逃”出模态框,也不能陷入背景内容。需手动拦截并循环聚焦在模态内可聚焦元素之间。
- 监听 keydown 事件,检测 Tab 键
- 收集所有可聚焦子元素:
const focusables = Array.from(modal.querySelectorAll(/* 同上选择器 */)); - 获取当前焦点索引,按下 Tab 时:若在最后一个元素 → 聚焦第一个;若在第一个且 Shift+Tab → 聚焦最后一个
关闭时正确恢复焦点与状态
模态框关闭后,焦点应回到触发它的元素(如“打开弹窗”按钮),同时确保屏幕阅读器感知到模态已移除。
Smile企业费用管理系统源码1.0
0
一、源码特点企业费用管理系统,有权限分配,登陆验证,新增角色,发布公告等二、功能介绍1、js的兼容性有个地方不行(比如模块排序,那个时候也是雏鸟一只,写了一小撮,现在用jq应该好处理的吧,ie里面没问题,大家发挥吧)2、里面的菜单和对应菜单下面的目录项可以根据需求自己添加的,有对应模块3、可以根据自己设定的角色添加对应的访问页面4、有些操作涉及到按钮权限,对于这种思路,我粗粗的写了2个自定义控件,
0 立即学习“Java免费学习笔记(深入)”;
- 关闭前记录触发元素(例如点击按钮时存为 triggerEl),关闭后调用 triggerEl.focus()
- 设置 aria-hidden=”true” 在模态父容器上,并在显示时设为 false;配合 role=”dialog” 和 aria-labelledby(指向标题 ID)提升语义
- 避免用 display: none 隐藏模态——它会从可访问树中完全移除;推荐用 visibility: hidden; position: absolute; left: -9999px 或 ARIA 的 aria-modal=”true”(现代支持良好)
补充关键细节
- ESC 键必须关闭模态框,并恢复焦点
- 点击遮罩层(backdrop)关闭时,也应触发相同焦点恢复逻辑
- 模态框内若有表单,提交后不要意外关闭——除非明确设计如此;否则保持焦点在错误字段或提示上
- 移动端注意:ios safari 对 aria-modal 支持有限,仍建议搭配手动焦点限制
基本上就这些。不复杂但容易忽略——焦点流一旦断掉,对不少用户就是不可用的开始。