如何在 Electron JS 应用程序的多个窗口之间切换?
如果您有 Web 应用程序开发的先验知识并考虑开始构建桌面应用程序,那么您来对地方了。
ElectronJS是一个开源框架,可帮助使用简单的 HTML、CSS 和 JavaScript 开发跨平台桌面应用程序。即使您想使用 Angular 或 React 开发应用程序并尝试构建它的桌面版本,Electron JS 也为您提供相同的支持。 Electron 使用无头 Chromium 浏览器,它通过 Electron 自己的 API 提供对 Node JS API 的访问。
在任何 Web 应用程序中,当我们单击某些链接时,有时会在浏览器中打开一个包含新内容的新选项卡。此外,我们认为您在桌面应用程序的情况下观察到相同的行为。当我们单击任何桌面应用程序中的某个按钮时,它会在前一个窗口的顶部打开一个新窗口,并且在我们关闭顶部窗口(或新窗口)之前,主窗口将无法工作。 Electron 提供了基于按钮单击或单击任何链接打开多个窗口的功能。
为了便于理解,假设您开发了一个应用程序,并且您想在另一个窗口中打开“设置”页面。本教程将演示如何使用 Electron JS 在新窗口中打开设置页面。
我们假设您熟悉电子应用程序的基本设置(如果不熟悉,请通过创建基本电子应用程序)。需要在系统中安装 Node 和 npm 才能运行 Electron 应用程序。
项目结构:让我们从项目的基本结构开始,如下所示。
- node_modules :这包含在您执行npm init -y时创建的节点 JS 包
- app.js :这是主要的 Electron JS 文件,我们在其中指定应用程序窗口配置
- index.html :这是主要的 HTML 文件(将其视为我们应用程序的主页)
- package-lock.json :当我们修改 node_modules 或 package.json 中的某些内容时,该文件已由 npm 自动生成
- package.json :这个文件由 npm 生成,它包含我们项目的附加依赖项(如电子)和一些其他设置
- settings.html :这是设置 HTML 文件(将显示在设置窗口中)
包.json
{
"name": "electron-app",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"start": "electron ."
},
"author": "Sandip",
"license": "ISC",
"dependencies": {
"electron": "^12.0.2"
}
}
将主脚本文件 ( main.js ) 从 Create Basic Electron Application 复制到我们的app.js ,它作为我们应用程序的主进程。
在index.html中编写简单的 HTML 代码(就好像它是你的第一个窗口或主窗口一样)如下
index.html
First Window
Hello : This is first window
app.js
const { app, BrowserWindow, ipcMain } = require("electron");
const path = require("path");
let mainWindow;
// Function to create independent window or main window
function createWindow() {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
// Make sure to add webPreferences with
// nodeIntegration and contextIsolation
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
},
show: false,
});
// Main window loads index.html file
mainWindow.loadFile("index.html");
// To maximize the window
mainWindow.maximize();
mainWindow.show();
}
// Function to create child window of parent one
function createChildWindow() {
childWindow = new BrowserWindow({
width: 1000,
height: 700,
modal: true,
show: false,
parent: mainWindow, // Make sure to add parent window here
// Make sure to add webPreferences with below configuration
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true,
},
});
// Child window loads settings.html file
childWindow.loadFile("settings.html");
childWindow.once("ready-to-show", () => {
childWindow.show();
});
}
ipcMain.on("openChildWindow", (event, arg) => {
createChildWindow();
});
app.whenReady().then(() => {
createWindow();
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
});
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});
Javascript
const ipc = window.require('electron').ipcRenderer;
// Function that will be called on click
// event of "Go to settings window" button
function goToSettingsWindow(){
// Make sure to do ipc.send('some String'),
// where 'some String' must be same with
// the first parameter of ipcMain.on() in app.js
ipc.send('openChildWindow');
}
settings.html
Settings
Hello : This is Settings window
Javascript
const remote = window.require("electron").remote;
function goToFirstWindow() {
//code for some other action to be performed
//Code to close the window after doing other actions
remote.getCurrentWindow().close();
}
输出:
app.js:我们打算在您单击“转到设置窗口”按钮时打开一个新的设置窗口。让我们检查一下app.js文件中要进行的必要更改。
应用程序.js
const { app, BrowserWindow, ipcMain } = require("electron");
const path = require("path");
let mainWindow;
// Function to create independent window or main window
function createWindow() {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
// Make sure to add webPreferences with
// nodeIntegration and contextIsolation
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
},
show: false,
});
// Main window loads index.html file
mainWindow.loadFile("index.html");
// To maximize the window
mainWindow.maximize();
mainWindow.show();
}
// Function to create child window of parent one
function createChildWindow() {
childWindow = new BrowserWindow({
width: 1000,
height: 700,
modal: true,
show: false,
parent: mainWindow, // Make sure to add parent window here
// Make sure to add webPreferences with below configuration
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true,
},
});
// Child window loads settings.html file
childWindow.loadFile("settings.html");
childWindow.once("ready-to-show", () => {
childWindow.show();
});
}
ipcMain.on("openChildWindow", (event, arg) => {
createChildWindow();
});
app.whenReady().then(() => {
createWindow();
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
});
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});
- 从电子模块导入ipcMain
- 如上添加createChildWindow()方法,基本上包含了子窗口(即设置窗口)的所有设置和配置
- 如果你这样做了, childWindow.parent = mainWindow同上,那么在子窗口关闭之前,父窗口将被禁用。
- 如果省略childWindow.parent ,则会打开一个新窗口,但子窗口和父窗口之间不会有任何联系。
- 包括ipcMain.on('openChildWindow', (event, arg) => { createChildWindow(); } );基本上调用 createChildWindow() 方法,同时我们通过 ipcRenderer 在按钮单击时发送“ openChildWindow”事件。
- 将具有上述所有键值的webPreferences属性添加到mainWindow对象,这使我们能够使用 Electron 的远程 ipcRenderer 来处理子窗口。
让我们在index.html中添加以下脚本
Javascript
const ipc = window.require('electron').ipcRenderer;
// Function that will be called on click
// event of "Go to settings window" button
function goToSettingsWindow(){
// Make sure to do ipc.send('some String'),
// where 'some String' must be same with
// the first parameter of ipcMain.on() in app.js
ipc.send('openChildWindow');
}
这里我们使用电子模块的ipcRenderer发送事件' openChildWindow '并且 ipcMain (在app.js中指定)正在监听这个事件并调用createChildWindow()方法。
让我们创建一个settings.html文件,该文件将在主窗口中单击按钮(“转到设置窗口”按钮)时显示在子窗口中。
设置.html
Settings
Hello : This is Settings window
输出:在添加“转到主窗口”功能之前,让我们检查打开设置窗口的输出
让我们在settings.html中添加以下脚本来关闭设置窗口并返回主窗口(如果通过单击窗口关闭(右上角的X按钮)关闭窗口,也可以,但有时我们需要在关闭窗口之前执行一些其他操作,例如数据库更新或配置更新,为此,您需要在单击按钮时关闭窗口)
Javascript
const remote = window.require("electron").remote;
function goToFirstWindow() {
//code for some other action to be performed
//Code to close the window after doing other actions
remote.getCurrentWindow().close();
}
在这里,我们正在访问电子模块的远程对象以获取 currentWindow 对象。
输出:让我们检查一下我们的最终应用程序。