You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Electron/React视频播放器全屏切换后ESC按键无响应问题求助

解决Electron/React视频播放器全屏后ESC键无响应问题

问题原因

  1. 全屏模式下,浏览器/Electron默认会捕获ESC键用于退出全屏,导致React组件的键盘事件监听器无法触发。
  2. React元素默认不可聚焦,全屏后焦点可能转移到浏览器的全屏容器而非你的播放器组件,进而无法触发组件上的onKeyDown事件。
  3. App.js中的全局按键监听失效,是因为全屏状态下焦点不在App根元素上,事件无法冒泡到该层级。

解决方案

方案1:让播放器容器可聚焦并手动获取焦点

修改Player.js,给播放器容器添加可聚焦属性,并在切换全屏后手动聚焦容器:

// Player.js
const Player = (props) => {
    const playerContainerRef = useRef(null);

    const handleFullscreen = () => {
        if (screenfull.isEnabled) {
            screenfull.toggle(playerContainerRef.current);
            // 延迟确保全屏状态生效后,聚焦容器
            setTimeout(() => {
                if (screenfull.isFullscreen) {
                    playerContainerRef.current?.focus();
                }
            }, 100);
        }
    };

    const handleKeyDown = (e) => {
        console.log(e.code);
        if (e.code === 'Escape' && screenfull.isFullscreen) {
            screenfull.exit();
            e.preventDefault(); // 避免默认退出行为重复触发
        }
    };

    return (
        <div 
            ref={playerContainerRef} 
            onKeyDown={handleKeyDown} 
            tabIndex="-1" // 让div可聚焦,不参与tab导航
            style={{ outline: 'none' }} // 移除聚焦时的默认边框
        >
            <div onDoubleClick={handleFullscreen}>
                <video />
            </div>
        </div>
    );
};

方案2:监听全局document键盘事件(更可靠)

直接在Player.js中监听document的键盘事件,不受焦点影响:

// Player.js
const Player = (props) => {
    const playerContainerRef = useRef(null);

    const handleFullscreen = () => {
        if (screenfull.isEnabled) {
            screenfull.toggle(playerContainerRef.current);
        }
    };

    // 挂载时添加全局键盘监听,卸载时移除
    useEffect(() => {
        const handleGlobalKeyDown = (e) => {
            if (e.code === 'Escape' && screenfull.isFullscreen) {
                screenfull.exit();
            }
        };
        document.addEventListener('keydown', handleGlobalKeyDown);
        return () => {
            document.removeEventListener('keydown', handleGlobalKeyDown);
        };
    }, []);

    return (
        <div ref={playerContainerRef}>
            <div onDoubleClick={handleFullscreen}>
                <video />
            </div>
        </div>
    );
};

方案3:修复App.js全局监听失效问题

将App.js中的按键监听改为绑定到document,而非组件元素:

// App.js
useEffect(() => {
    const handleKeyDown = (e) => {
        e.preventDefault();
        switch (e.code) {
            case 'Space':
                refs.playerRef.current?.play();
                break;
            case 'ArrowLeft':
                refs.playerRef.current?.seekBackward();
                break;
            case 'ArrowRight':
                refs.playerRef.current?.seekForward();
                break;
            case 'NumpadAdd':
                refs.playerRef.current?.increaseSpeed();
                break;
            case 'NumpadSubtract':
                refs.playerRef.current?.decreaseSpeed();
                break;
            case 'Escape':
                if (screenfull.isFullscreen) {
                    screenfull.exit();
                }
                console.log('Pressed ESC');
                break;
            default:
                break;
        }
    };
    document.addEventListener('keydown', handleKeyDown);
    return () => {
        document.removeEventListener('keydown', handleKeyDown);
    };
}, []);

内容的提问来源于stack exchange,提问作者fr0zie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 04:35:55