专注时钟的空格键:页面快捷键与按钮原生点击怎样避免冲突
给计时器加空格键快捷操作,看起来只要监听一次 keydown。但页面上本来就有“开始 / 暂停”按钮:当焦点停在按钮上,浏览器会把空格键解释成按钮点击。如果文档级快捷键也同时切换状态,一次按键可能执行两次,表面上就像计时器完全没启动。
我检查了《节奏·专注时钟》的实际单文件代码,焦点落在按钮时,文档监听器选择不处理:
document.addEventListener('keydown', e => {
if (e.code === 'Space' && !e.repeat &&
!['BUTTON','INPUT','TEXTAREA','SELECT'].includes(e.target.tagName)) {
e.preventDefault();
toggle();
}
});
这段判断有三层边界。第一,e.code 对应物理按键,这里只管空格。第二,e.repeat 拦住长按时自动重复的 keydown,避免专注状态在“运行”和“暂停”之间来回切换。第三,按钮及输入控件沿用自身键盘行为;当焦点在普通页面区域,才由文档快捷键处理,并调用 preventDefault() 防止页面因空格滚动。
测试不能只把键盘事件手动派发到页面上。手动派发的事件不代表浏览器一定会执行按钮的原生默认行为。我用真实浏览器对原HTML实际按键:在页面空白区域按空格,状态变为“保持节奏”;再按一次,变为“已暂停”。额外派发 repeat:true 的 keydown,状态保持运行。切到5分钟短休息后显示05:00且回到准备状态;把焦点放到“开始休息”按钮再按空格,浏览器原生点击只启动一次。最后点“重新计时”,显示05:00并停止运行。7个观察结果已留在本地验证记录,源文件未改。
这里还有一个容易漏的交互:切换模式本身会重新计时,不能把上一个模式的剩余时间带进新模式。代码里的模式按钮先用新时长替换状态,再刷新显示;“重新计时”也直接恢复当前模式的整段时长。通过检查可见时间和状态,可以同时验证用户读到的结果,而不只是内部变量。
这次检查覆盖了真实浏览器里的键盘与按钮交互,没有等待25分钟走完整轮,也没有验证通知、后台计时精度或各种输入法。页面快捷键的原则是先尊重当前焦点控件,再处理普通页面区域;测试时要用真实按键走一遍,才能看见浏览器原生行为与自己的监听器是否打架。
作品展示:华为云开发者作品展览馆中的《节奏·专注时钟》。
- 点赞
- 收藏
- 关注作者
评论(0)