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

Next.js 14全屏防误退出功能代码修复求助

重写后的Next.js 14全屏功能组件

以下是修复后的代码,解决了原代码中状态不同步、事件监听逻辑问题,确保功能正常运行:

"use client";
import { useEffect, useState } from "react";

export default function FullScreenTest() {
  const [isFullScreen, setIsFullScreen] = useState(false);
  const [showExitWarning, setShowExitWarning] = useState(false);

  // 进入全屏
  const enterFullScreen = async () => {
    const root = document.documentElement;
    try {
      if (root.requestFullscreen) {
        await root.requestFullscreen();
      } else if (root.webkitRequestFullscreen) {
        await root.webkitRequestFullscreen();
      } else if (root.mozRequestFullScreen) {
        await root.mozRequestFullScreen();
      } else if (root.msRequestFullscreen) {
        await root.msRequestFullscreen();
      }
    } catch (err) {
      console.error("进入全屏失败:", err);
    }
  };

  // 退出全屏
  const exitFullScreen = async () => {
    try {
      if (document.exitFullscreen) {
        await document.exitFullscreen();
      } else if (document.webkitExitFullscreen) {
        await document.webkitExitFullscreen();
      } else if (document.mozCancelFullScreen) {
        await document.mozCancelFullScreen();
      } else if (document.msExitFullscreen) {
        await document.msExitFullscreen();
      }
    } catch (err) {
      console.error("退出全屏失败:", err);
    }
  };

  // 监听全屏状态变化
  useEffect(() => {
    const handleFullscreenChange = () => {
      const currentFullScreen = !!document.fullscreenElement || 
                              !!document.webkitFullscreenElement || 
                              !!document.mozFullScreenElement || 
                              !!document.msFullscreenElement;
      setIsFullScreen(currentFullScreen);
      if (!currentFullScreen) {
        setShowExitWarning(false); // 退出全屏后重置警告状态
      }
    };

    // 添加各浏览器前缀的全屏变化监听
    document.addEventListener("fullscreenchange", handleFullscreenChange);
    document.addEventListener("webkitfullscreenchange", handleFullscreenChange);
    document.addEventListener("mozfullscreenchange", handleFullscreenChange);
    document.addEventListener("MSFullscreenChange", handleFullscreenChange);

    return () => {
      document.removeEventListener("fullscreenchange", handleFullscreenChange);
      document.removeEventListener("webkitfullscreenchange", handleFullscreenChange);
      document.removeEventListener("mozfullscreenchange", handleFullscreenChange);
      document.removeEventListener("MSFullscreenChange", handleFullscreenChange);
    };
  }, []);

  // 监听Escape键事件
  useEffect(() => {
    const handleEscapeKey = (e) => {
      if (e.key !== "Escape" || !isFullScreen) return;

      if (!showExitWarning) {
        e.preventDefault(); // 阻止第一次Escape直接退出全屏
        alert("Are you sure you want to exit full view?");
        setShowExitWarning(true);
      } else {
        exitFullScreen();
        setShowExitWarning(false);
      }
    };

    window.addEventListener("keydown", handleEscapeKey);
    return () => window.removeEventListener("keydown", handleEscapeKey);
  }, [isFullScreen, showExitWarning]);

  const handleStartTest = () => {
    // 这里可以添加测试开始的逻辑
    console.log("测试已启动");
  };

  return (
    <div style={{ padding: "2rem", textAlign: "center" }}>
      {!isFullScreen ? (
        <button 
          onClick={enterFullScreen}
          style={{ padding: "0.8rem 1.5rem", fontSize: "1rem", cursor: "pointer" }}
        >
          开始测试(进入全屏)
        </button>
      ) : (
        <div>
          <h1>测试进行中...</h1>
          <button 
            onClick={handleStartTest}
            style={{ marginTop: "1rem", padding: "0.8rem 1.5rem", fontSize: "1rem", cursor: "pointer" }}
          >
            启动测试
          </button>
        </div>
      )}
    </div>
  );
}

关键修复点说明

  • 状态同步问题:不再直接在enterFullScreen中设置isFullScreen,而是通过fullscreenchange事件监听实际的全屏状态,确保状态与浏览器实际情况一致。
  • 异步处理:全屏操作是异步的,添加async/await并捕获异常,避免错误导致状态异常。
  • Escape键逻辑优化:确保只有在全屏状态下才处理Escape键,第一次按下时阻止默认退出行为并弹出提示,第二次按下才执行退出。
  • 浏览器兼容性:保留了各主流浏览器的前缀支持,覆盖Chrome、Firefox、Edge等。
  • 警告状态重置:退出全屏后自动重置警告状态,避免再次进入全屏时状态残留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 18:27:23