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
相关产品推荐
相关产品推荐

