ElectronJS:如何为点击事件创建无菜单栏的新窗口
window.open()创建的子窗口仍显示菜单栏的问题 这个问题我之前也踩过坑!Electron 里网页内调用的 window.open() 并不是浏览器原生的弹窗机制,而是被 Electron 用 BrowserWindowProxy 包装过的。你写的 toolbar=no 这类网页端参数,Electron 并不完全买账,而且通过这种方式创建的窗口,你没法直接拿到对应的 BrowserWindow 实例,自然也就没法像主窗口那样调用 setMenu(null) 去移除菜单栏。
下面给你两种可行的解决方案,推荐第一种,更可靠也更灵活:
方案一:拦截window.open请求,手动创建子窗口(推荐)
这种方式能让你完全掌控子窗口的所有配置,包括菜单栏、大小、工具栏这些,而且不依赖任何可能被废弃的API。
步骤:
- 在主窗口的
webContents上监听new-window事件——这个事件会在网页里调用window.open()时自动触发。 - 在事件回调里,我们手动创建一个新的
BrowserWindow,把想要的配置都加上(比如移除菜单栏、指定窗口大小),同时阻止Electron默认的窗口创建行为。
示例代码:
在你的 main.js 里,主窗口创建的代码后面加上这段:
// 先保留你原来的主窗口创建代码 const mainWindow = new BrowserWindow({ width: 800, // 你的主窗口宽度 height: 600, // 你的主窗口高度 webPreferences: { nodeIntegration: true, // 根据你的Electron版本调整,新版本可能需要配合contextIsolation contextIsolation: false } }); // 移除主窗口菜单栏(你原来的代码) mainWindow.setMenu(null); // 重点:拦截网页内的window.open请求 mainWindow.webContents.on('new-window', (event, url, frameName, disposition, options) => { // 先阻止Electron默认的窗口创建行为 event.preventDefault(); // 检查是不是我们要打开的addNew.html页面 if (url.includes('addNew.html')) { // 手动创建子窗口 const addWindow = new BrowserWindow({ width: 900, height: 400, resizable: false, menu: null, // 直接在这里移除菜单栏! webPreferences: { nodeIntegration: true, contextIsolation: false } }); // 加载目标页面 addWindow.loadFile('addNew.html'); // 可选:窗口关闭时释放资源,避免内存泄漏 addWindow.on('closed', () => { addWindow = null; }); } });
然后你的网页里的按钮代码可以简化成这样,不需要那些网页端的参数了:
<button onclick="window.open('addNew.html', 'Add New Item')">添加项目</button>
这样一来,不管你网页里传什么参数,都会被我们的拦截逻辑接管,用Electron原生的窗口配置来创建子窗口,保证菜单栏被彻底移除。
方案二:开启nativeWindowOpen选项,直接操作子窗口实例
如果你不想改主进程的代码,也可以通过开启Electron的nativeWindowOpen选项,让window.open()返回的对象能关联到真实的BrowserWindow实例,然后手动移除菜单栏。
步骤:
- 在主窗口的
webPreferences里开启nativeWindowOpen: true。 - 在网页里调用
window.open()后,通过remote模块获取到真实的窗口实例,再调用setMenu(null)。
示例代码:
首先在main.js的主窗口配置里加上nativeWindowOpen: true:
const mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, contextIsolation: false, enableRemoteModule: true, // 注意:Electron14+默认禁用remote,需要手动开启 nativeWindowOpen: true // 开启原生窗口打开模式 } }); mainWindow.setMenu(null);
然后网页里的按钮代码改成这样:
<button onclick="openAddWindow()">添加项目</button> <script> function openAddWindow() { // 打开窗口,这里的网页参数可以保留 const winProxy = window.open('addNew.html', 'Add New Item', 'width=900,height=400,resizable=no'); // 通过remote模块获取真实的BrowserWindow实例 const electron = require('electron'); const realAddWindow = electron.remote.BrowserWindow.fromWebContents(winProxy.webContents); // 移除菜单栏 realAddWindow.setMenu(null); } </script>
不过要注意:remote模块在Electron 14及以上版本默认是禁用的,而且官方未来可能会移除这个模块,所以这个方案只是临时应急用,还是推荐第一种方案。
内容的提问来源于stack exchange,提问作者akalanka

