
在 Electron + React 构建的视频播放器中,局部 onKeyDown 事件无法捕获全屏状态下的 ESC 键,需改用全局 document.addEventListener('keydown') 并结合 screenfull 库实现可靠响应。
在 electron + react 构建的视频播放器中,局部 `onkeydown` 事件无法捕获全屏状态下的 esc 键,需改用全局 `document.addeventlistener('keydown')` 并结合 `screenfull` 库实现可靠响应。
当 Web 应用进入全屏模式(尤其是通过 screenfull.js 或原生 Element.requestFullscreen())后,焦点行为会发生变化:浏览器会将键盘事件优先派发给顶层文档(document),而非某个特定 DOM 元素(如 <div ref={playerContainerRef}>)。因此,依赖组件内 onKeyDown 属性绑定的事件处理器在全屏状态下将失效——这正是你观察到“ESC 在非全屏时有效、全屏后失效”的根本原因。
✅ 正确方案:使用全局 document 监听 + useEffect 清理
推荐采用 React 的 useEffect Hook,在组件挂载时为 document 添加 keydown 监听器,并在卸载时自动移除,确保内存安全与事件精准触发:
import React, { useRef, useEffect } from 'react';
import screenfull from 'screenfull';
const Player = (props) => {
const playerContainerRef = useRef(null);
useEffect(() => {
const handleKeyDown = (e) => {
// 同时兼容 e.code 和 e.key(部分环境 e.code 可能为空)
if (e.code === 'Escape' || e.key === 'Escape') {
e.preventDefault(); // 阻止浏览器默认行为(如关闭 DevTools)
if (screenfull.isFullscreen) {
screenfull.exit().catch(err => {
console.warn('Failed to exit fullscreen:', err);
});
}
}
};
document.addEventListener('keydown', handleKeyDown);
// 清理函数:组件卸载时移除监听器
return () => {
document.removeEventListener('keydown', handleKeyDown);
};
}, []); // 空依赖数组 → 仅在挂载/卸载时执行
const handleFullscreen = () => {
if (playerContainerRef.current) {
screenfull.toggle(playerContainerRef.current);
}
};
return (
<div ref={playerContainerRef}>
<div onDoubleClick={handleFullscreen}>
<video
src={props.src}
controls
style={{ width: '100%', height: 'auto' }}
/>
</div>
</div>
);
};
export default Player;⚠️ 关键注意事项
- e.preventDefault() 不可省略:尤其在 Electron 环境中,ESC 默认可能触发窗口控制行为(如退出 DevTools 或关闭窗口),显式调用可避免干扰。
- screenfull.exit() 返回 Promise:应使用 .catch() 处理可能的拒绝(例如用户主动退出全屏导致重复调用),提升健壮性。
- 避免重复监听:务必通过 useEffect 清理机制移除监听器,否则组件多次渲染可能导致多个相同监听器叠加,引发重复执行。
- 依赖项谨慎设置:此处 useEffect 依赖为空数组 [],确保监听器只注册一次;若需动态响应 screenfull 状态变化(如监听 screenfull.on('change')),可扩展依赖项并加入状态管理。
- Electron 特殊场景补充:若应用启用了 nodeIntegration: true 或自定义菜单,还需检查主进程是否拦截了 ESC 事件(可通过 app.disableHardwareAcceleration() 或 webPreferences 配置验证)。
通过该方案,ESC 键无论在普通视图、全屏播放,甚至退出全屏后的过渡态中,均能稳定触发退出逻辑,兼顾兼容性、可维护性与用户体验。



















