J3.02.4focus management设计研究

动态插入的元素若不显式管理焦点,会默认停留在原处造成脱节

别名: 动态焦点 · 插入后焦点 · focus after insertion

概念解释

提交之后页面插入了一条错误、点了「添加一项」列表多出一行、筛选结果替换了整块内容——这些时刻,浏览器默认不移动焦点。焦点仍停在刚才按下的按钮上,新内容出现在别处。键盘用户和下一个该处理的对象已经不在同一处,这叫插入后的焦点脱节

播报新内容和解脱节不是一回事。实时区域可以让阅读器开口,焦点仍可能留在旧按钮上;下一步 Tab 走的还是旧位置旁边,不是刚出现的字段。

机制

用户代理把焦点当作「用户上一次明确选中的节点」。DOM 插入、Ajax 替换、路由切视图,都不是一次明确的用户选中,所以焦点节点若还在文档里,就原地不动;若被销毁,焦点往往掉到 body。无论哪种,空间模型和序列模型都断了:看得见的人要在新块和旧按钮之间来回找,看不见的人听到「出错了」却按 Tab 走进无关区域。

该不该把焦点移过去,取决于插入的是什么。阻断性错误、新打开的对话、用户刚请求创建的字段,应当成为焦点。后台「已保存」提示不应当抢焦点。缺的是这条显式决策——不是浏览器忘了帮忙,是产品没有把「工作对象换了」写成一次焦点移动。

怎么研究

选三类插入:表单校验错误、列表末尾新增项、无刷新的整块结果替换。触发后立刻问:焦点在哪个节点、下一个 Tab 落到哪、屏幕阅读器是否开口。三问分开记,不要用「有提示」代替「焦点已到」。

对照:同样操作在整页刷新的旧站点上,焦点通常会落到新页顶部或第一个字段——那是导航重建,不是插入。单页应用用插入冒充导航时,脱节最严重。

边界

聊天室、日志、协作光标这类持续流入的内容,若每条都抢焦点,用户无法打字。这类流用实时区域通知即可,不要移焦点。用户正在输入时插入的非阻断提示,也不得夺走输入框。相反,支付失败、权限拒绝、会话将过期,插入后若不把焦点移到可操作的那条消息,键盘用户可能在已经失效的提交按钮上反复按 Enter。

怎么落地

  • 插入阻断性消息或用户刚请求的新字段时,把焦点移到该消息或字段;不要只改 DOM。
  • 节点被销毁前,先把焦点送到仍然存在、且与任务相关的节点,避免落到 body
  • 非阻断的「已保存」不要抢焦点;用实时区域通知即可。
  • 验证:提交一个会失败的表单,手不离开键盘。焦点若仍停在提交按钮,而错误出现在屏幕另一头,脱节已经发生。

延伸

  • 同组J3.02.1 焦点顺序需与视觉顺序一致 · J3.02.2 浮层需捕获焦点并可退出 · J3.02.3 无法退出的焦点陷阱是阻断性缺陷 · J3.02.5 焦点顺序应随可见的动态变化(如展开、隐藏)实时更新 · J3.02.6 检测焦点顺序问题需要实际用键盘遍历而非仅检查代码顺序 · J3.02.7 多层嵌套的浮层各自捕获焦点时可能相互冲突形成死锁
  • 相邻J5.12 动态内容的播报 · J2.07 低视力与屏幕放大 · J4.11 一致性作为认知支持
  • 站内检索focus management · dynamic insertion · focus after update

同组卡片

快捷操作

分享

分享当前页面

ios_share

https://hci.top/zh/handbook/J3.02.4