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

Next.js全屏退出状态不同步问题:ESC按键需按两次如何解决?

问题解决思路

问题核心在于你仅通过监听ESC按键更新状态,但系统自带的全屏退出(包括ESC触发的场景)无法保证组件状态与实际全屏状态同步,同时缺少对全屏状态变化的通用监听,另外未清理事件监听还可能导致内存泄漏。

具体修复方案

  • 监听fullscreenchange事件:这是浏览器原生的全屏状态变化事件,无论通过ESC、浏览器按钮还是代码触发的全屏/退出操作,都会触发该事件,通过document.fullscreenElement可直接判断当前是否处于全屏状态。
  • 清理事件监听:在useEffect的返回函数中移除添加的事件监听,避免组件卸载后事件残留。
  • 优化全屏触发逻辑:requestFullscreen是异步操作,在其成功回调中更新状态,确保状态与实际全屏状态完全匹配。

修改后的完整代码

'use client'

import { useState, useEffect } from 'react'

const App = () => {
  const [isFScreen, setIsFScreen] = useState(false)

  useEffect(() => {
    // 同步全屏状态变化
    const handleFullscreenChange = () => {
      setIsFScreen(!!document.fullscreenElement)
    }

    // 处理ESC按键(可选,fullscreenchange已覆盖状态同步,保留可主动触发退出)
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === "Escape" && document.fullscreenElement) {
        document.exitFullscreen()
      }
    }

    document.addEventListener("fullscreenchange", handleFullscreenChange)
    document.addEventListener("keydown", handleKeyDown)

    // 组件卸载时清理事件监听
    return () => {
      document.removeEventListener("fullscreenchange", handleFullscreenChange)
      document.removeEventListener("keydown", handleKeyDown)
    }
  }, [])

  const toggleFullscreen = () => {
    const gameScreen = document.getElementById("gameScreen")
    if (!gameScreen) return

    if (!isFScreen) {
      gameScreen.requestFullscreen().then(() => {
        setIsFScreen(true)
      }).catch(err => {
        console.error("进入全屏失败:", err)
      })
    } else {
      document.exitFullscreen().then(() => {
        setIsFScreen(false)
      }).catch(err => {
        console.error("退出全屏失败:", err)
      })
    }
  }

  return(
    <div id="gameScreen">
     <span onClick={toggleFullscreen}>
       {isFScreen ? '退出全屏' : '全屏'}
     </span>
    </div>
  )
}

export default App

关键改动说明

  • fullscreenchange监听:确保任何场景下的全屏状态变化都能同步到组件状态,彻底解决ESC退出后状态不同步的问题。
  • 事件清理:避免组件重复渲染或卸载后残留事件监听,防止内存泄漏。
  • 异步状态更新:利用全屏操作的Promise回调更新状态,保证状态与实际全屏状态完全一致。
  • 动态按钮文本:根据当前状态切换按钮显示内容,提升用户体验。

内容的提问来源于stack exchange,提问作者co-flow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 04:35:12