E2.22.4unsolicited focus steal设计研究

非用户触发的焦点跳转会打断正在进行的输入

别名: 焦点抢夺 · focus stealing · 打字时被拽走

概念解释

人正在一个槽里打字,脚本或后到的内容把焦点拽到别处:异步校验把焦点跳到第一个错误、广告、聊天消息、晚到的自动聚焦。正在组的词被写进错误的槽,或半截留在旧槽。未经请求的焦点抢夺(unsolicited focus steal)是输入进行中的打断,不是页面刚打开时的播报顺序,也不是用户自己点开弹层后的正当交接。

机制

键入是一条连续的运动计划,插入点是计划钉在界面上的钉子。钉子在两次按键之间被搬走,后续字符落在新钉子上,两条槽的内容都脏了。IME 组字缓冲区更脆:抢夺发生在上屏前,音节丢失或打进别的应用。抢夺的来源经常是「好心」:校验想带人去错误、客服聊天想提示新消息、单页应用路由想聚焦主内容。对正在写的人,这些都是同一件事——插入点不听话。用户自己的 Tab、点击、打开菜单不是抢夺,因为钉子是他们搬的。

怎么研究

让人在槽里持续打一段话,期间触发异步错误、插入通知、路由局部更新,记录焦点是否离开、错槽中的字符、组字是否丢失。自变量:抢夺是否发生在 compositionstart 期间、是否可配置。因变量:错置字符数、愤怒撤销、放弃。触屏上弹出的键盘收起再抬起也是一种抢夺,应单独条件。不要在空闲的槽上测——空闲时跳转的代价低,掩盖进行中的损失。

边界

用户刚点提交,焦点跳到第一个错误是被请求的导航,只要发生在提交之后、而不是还在改别的字段时。会话超时把焦点拉到登录,打断是真的,但安全优先;应尽量保留未提交草稿。协作光标、他人编辑不应夺走本地焦点。游戏和远程桌面有自己的焦点协议,网页规则不能照搬。

怎么落地

  • 禁止在正在组成或正在键入时调用 focus();把错误提示做成不抢焦点的内联信息,提交后再移动焦点。
  • 聊天、通知、广告不得抢正在编辑的插入点。
  • 路由更新若必须设焦点,避开 document.activeElement 已是输入类控件的情况。
  • 验证:在槽里打字并开着输入法,让校验、通知、局部刷新同时发生。插入点若跳走或半个拼音失踪,就是抢夺。提交之后跳到错误字段则应发生。

延伸

  • 同组E2.22.1 页面加载即聚焦会打断屏幕阅读器的顺序播报 · E2.22.2 自动聚焦适合唯一且明确的首要输入框 · E2.22.3 弹层打开后应主动移交焦点,关闭后应归还
  • 相邻E6.03 内联校验提示 · E2.16 自动补全下拉
  • 站内检索unsolicited focus steal · focus stealing · composition interruption

同组卡片

快捷操作

分享

分享当前页面

ios_share

https://hci.top/zh/handbook/E2.22.4