E2.22.3dialog focus handoff设计研究
弹层打开后应主动移交焦点,关闭后应归还
别名: 模态焦点捕获 · focus trap · 关闭后焦点回去
概念解释
对话框、抽屉、菜单打开时,键盘和读屏器仍停在底下那一页,等于对着一块看不见的层打字。打开时应把焦点交进弹层;关掉后应还给打开它的那个控件。这叫弹层焦点交接(dialog focus handoff)。它管的是一层界面的进入与退出,不是整页加载时该不该自动聚焦,也不是异步脚本在输入中途抢焦点。
机制
模态在视觉上切断了底下的页,焦点若不跟着走,键盘用户继续 Tab 会在底层不可见控件上转,读屏器仍读底层。交进去通常落在弹层标题或第一个可操作控件,并在层内循环(焦点陷阱),避免逃回底下。关掉时若焦点掉到文档开头或 body,人丢失「我刚才在哪」,得重新找触发按钮。归还到触发者,是把一次往返做成可逆的位置记忆。非模态面板不该陷阱,但仍应在打开时把焦点送进面板,关闭时归还,否则打开等于没打开。
怎么研究
用键盘打开对话框,看焦点是否进入层内、Tab 是否被关在层里、Esc 关闭后焦点是否回到触发按钮。自变量:初始焦点落在标题还是第一字段、是否有焦点陷阱、关闭动画是否把焦点弄丢。因变量:逃出到底层的次数、关闭后重新定位触发者的时间。读屏器应听到弹层的名称。对照已建立的对话框焦点模式做走查,测的是往返是否可逆,不是属性清单。
边界
通知气泡、短暂吐司不应抢焦点,否则正在打的字会被拽走——那是另一条「不要抢」。全屏路由式「弹层」其实是新页,关闭应走浏览历史而不是归还已卸载的按钮。嵌套弹层要归还到上一层,不是一次跳回最底层触发者。触屏没有 Tab 陷阱问题,但关闭后滚动位置和触发者仍应在视口里。
怎么落地
- 打开弹层时把焦点送到层内(标题或首个字段),并在层内循环直到关闭。
- 关闭时把焦点还给触发控件;控件已不在则给一个合理的附近位置并让它可见。
- 读屏器要能听到弹层名称;不要只移动焦点不改可访问名称。
- 验证:Tab 打开一个对话框,在层内走一圈不得掉到底下;Esc 后焦点应在原按钮上。再测读屏器是否在打开时报了层的名字。