Electron+React v15.6.2类组件中webview全屏退出报错Document not active排查
Got it, let's break down why you're hitting this error and how to fix it in your React v15 class component setup.
Root Cause
The TypeError: Document not active happens because when you press Esc, your code first exits the main Electron window's fullscreen state before telling the webview to exit its own fullscreen. By the time the preload script runs document.exitFullscreen(), the webview's document is no longer the active context—so the browser rejects the call. Additionally, it's possible the fullscreen state is applied to a specific DOM element inside the webview, not the document itself.
Step-by-Step Fixes
1. Use React Refs to Reliably Access the WebView
Instead of document.querySelector('webview'), use a React ref to get the webview instance. This avoids race conditions where the DOM might not be fully rendered when you try to access the element.
Update your Play.js component:
import React, { Component } from 'react'; import { connect } from 'react-redux'; import { remote } from 'electron'; import { StyledWebview } from './styled'; class Play extends Component { constructor(props) { super(props); this.state = { isExpanded: false, height: 0, }; this.webviewRef = React.createRef(); // Initialize ref } componentDidMount() { this.updateWindowDimensions(); window.addEventListener('resize', this.updateWindowDimensions); const webviewTag = this.webviewRef.current; // Use ref to get webview webviewTag.addEventListener("dom-ready", () => { webviewTag.openDevTools(); }); webviewTag.addEventListener('leave-html-full-screen', () => { this.setState({ isExpanded: false }); }); webviewTag.addEventListener('enter-html-full-screen', () => { this.setState({ isExpanded: true }); }); webviewTag.getWebContents().on('before-input-event', (e, input) => { if (input.key === 'Escape') { // First tell the webview to exit fullscreen webviewTag.send('exitFullscreen', { data: '[DesktopClient]: exit fullscreen from container', }); // Then update local state and main window this.setState({ isExpanded: false }); const mainWindow = remote.getCurrentWindow(); if (mainWindow.isFullScreen()) { mainWindow.setFullScreen(false); } e.preventDefault(); // Block default Esc behavior to avoid conflicts } }); } componentWillUnmount() { window.removeEventListener('resize', this.updateWindowDimensions); } updateWindowDimensions = () => this.setState({ height: window.innerHeight }); render() { const { computedMatch, accessToken, memberId, refreshToken } = this.props; const { height, isExpanded } = this.state; const gameId = computedMatch.params.id; const src = `https://.......`; return ( <StyledWebview ref={this.webviewRef} // Attach ref to webview isExpanded={isExpanded} contentHeight={height} preload="./components/Play/Injection/preload.js" src={src} /> ); } } function mapStateToProps(state) { return { accessToken: state.auth.userAuthDetails.accessToken, memberId: state.auth.userAuthDetails.memberId, refreshToken: state.auth.userAuthDetails.refreshToken, }; } export default connect(mapStateToProps)(Play);
2. Update Preload Script to Target the Correct Fullscreen Element
Instead of calling document.exitFullscreen() directly, check if a specific element is in fullscreen mode (since games often fullscreen a canvas or container element, not the entire document). Add fallbacks for browser prefixes to cover edge cases.
Update preload.js:
const { ipcRenderer } = require('electron'); console.log('injected........'); ipcRenderer.on('exitFullscreen', () => { console.log('document:', document); // Get the active fullscreen element (with cross-browser fallbacks) const fullscreenElement = document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement; if (fullscreenElement) { // Exit fullscreen on the element itself if (fullscreenElement.exitFullscreen) { fullscreenElement.exitFullscreen(); } else if (fullscreenElement.webkitExitFullscreen) { fullscreenElement.webkitExitFullscreen(); } else if (fullscreenElement.mozCancelFullScreen) { fullscreenElement.mozCancelFullScreen(); } else if (fullscreenElement.msExitFullscreen) { fullscreenElement.msExitFullscreen(); } } else { // Fallback to exiting document fullscreen if no element is found try { document.exitFullscreen(); } catch (err) { console.warn('No active fullscreen context to exit:', err); } } });
Why This Works
- Refs: Ensures you're always accessing the correct webview instance, even if the DOM updates.
- Order of Operations: Tells the webview to exit fullscreen first while its document is still active, before modifying the main window's state.
- Element Targeting: Handles cases where the game uses a specific element for fullscreen instead of the document, which is common in web-based games.
This should resolve the "Document not active" error while keeping your code compliant with React v15's class component requirements.
内容的提问来源于stack exchange,提问作者Cristian Muscalu

