Idle Detection API 中需同时判断 userState 和 screenState:userState 反映交互活跃度('active'/'idle'),screenState 才是判定用户离座的关键('locked' 表示真离座),二者独立更新,不可单凭 userState === 'idle' 误判。

直接看 userState 和 screenState 两个字段
Idle Detection API 的 change 事件触发时,检测器实例上同时暴露 userState 和 screenState,二者独立更新、互不覆盖。不能只看其中一个来判断用户是否真正离开——比如 userState === 'idle' 只说明过去 60 秒没键盘/鼠标/触控交互,但用户可能正盯着屏幕发呆;而 screenState === 'locked' 才是更可靠的“人已离座”信号。
userState 的三种值对应不同行为意图
它反映的是用户与设备的**交互活跃度**,不是页面可见性:
-
'active':最近有任意输入事件(包括focus、input、touchstart等),或刚从idle恢复 -
'idle':连续 ≥ 阈值(如 60000)毫秒无交互,但屏幕仍亮着、页面在前台——此时用户可能只是暂停操作,不等于已走开 -
'locked':仅当系统级屏幕锁生效时才出现(如 Win+L、macOS 快捷锁屏、移动端息屏),此状态几乎可确认用户已物理离开
注意:userState 不会变成 'locked',那是 screenState 的专属值。
screenState 是判定“真离座”的关键依据
它由操作系统直接上报,精度远高于纯前端事件监听:
立即学习“前端免费学习笔记(深入)”;
-
'unlocked':屏幕正常点亮且未加锁,即使userState === 'idle',也不能假设用户已离开 -
'locked':屏幕已被系统锁定,此时基本可认为用户已中断使用——这是触发敏感内容锁定最稳妥的时机
常见误判场景:userState === 'idle' + screenState === 'unlocked' 时,不应立即隐藏表单或清空输入框,更适合降级为弱提示(如淡出非关键区域)或暂停自动轮询。
组合判断逻辑要写清楚,别只用 if (detector.userState === 'idle')
真实业务中需按安全等级区分响应动作:
- 高敏感操作(如银行转账确认页):只在
userState === 'locked' || screenState === 'locked'时执行 DOM 锁定(加data-locked="true"、禁用表单、暂停 WebSocket) - 中等敏感(如编辑未保存文档):
userState === 'idle'且页面document.visibilityState === 'visible'时开始倒计时提示,30 秒后若仍未恢复则暂存草稿并模糊敏感字段 - 低敏感(如仪表盘图表重绘):仅监听
userState === 'idle'即暂停计算,screenState不参与判断
容易忽略的一点:Chrome 94+ 中 screenState 在部分 Linux 桌面环境或虚拟机里可能始终返回 'unlocked',即使屏幕已锁——这时得 fallback 到 userState === 'locked'(注意不是 'idle')作为次强信号。



















