目录
关闭所有窗口时退出应用 (Windows & Linux)
前言
接上一篇文章
这一篇文章我们开始做第一个小demo
运行主进程
上一篇文章我们在根目录配置了package.json文件
任何 Electron 应用程序的入口都是 main
字段对应文件。 这个文件控制了主进程,它运行在一个完整的Node.js环境中,负责控制应用的生命周期,显示原生界面,执行特殊操作并管理渲染器进程(稍后详细介绍)。
执行期间,Electron 将依据应用中 package.json
配置下main字段中配置的值查找此文件。
我们在上一篇中配置了scripts字段中的start。此时我们可以执行以下命令来开始运行程序:
npm start
此时会弹窗并报错,提示你找不到main.js文件。
要初始化这个main
文件,需要在项目的根目录下创建一个名为main.js
的空文件。
创建完成后再次执行,效果如下
注意:这一次运行start
命令,应用将不再抛出任何错误! 然而,它不会做任何事因为我们还没有在main.js
中添加任何代码。
创建界面
在为我们的应用创建窗口前,我们需要先创建加载进该窗口的内容。 在Electron中,各个窗口显示的内容可以是本地HTML文件,也可以是一个远程url。
我们这里使用本地的HTML文件。
在项目根目录下创建一个名为index.html
的文件,内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
We are using Node.js <span id="node-version"></span>,
Chromium <span id="chrome-version"></span>,
and Electron <span id="electron-version"></span>.
</body>
</html>
注意:在这个HTML文本中,你会发现主体文本中丢失了版本编号。 稍后我们将使用 JavaScript 动态插入它们。
使用窗口打开界面
现在我们有了一个页面,下面需要将它加载进应用窗口中。 要做到这一点,你需要 两个Electron模块:
- app 模块,它控制应用程序的事件生命周期。
- BrowserWindow 模块,它创建和管理应用程序 窗口。
因为主进程通过Node.js运行,所以我们需要在 main.js文件开头
import这些模块。
const { app, BrowserWindow } = require('electron')
然后,添加一个createWindow()
方法来将index.html
加载进一个新的BrowserWindow
实例。
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
接着,调用createWindow()
函数来打开您的窗口。
在 Electron 中,只有在 app
模块的 ready 事件被激发后才能创建浏览器窗口。 您可以通过使用 app.whenReady() API来监听此事件。 在whenReady()
成功后调用createWindow()
。
app.whenReady().then(() => {
createWindow()
})
到这里,整个main.js文件应该是这样的
const { app, BrowserWindow } = require('electron')
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
})
保存后,在cmd中运行上面提到的开始命令:
npm start
此时你的“Hello World”窗口应该已经可以成功打开了。
管理窗口的生命周期
虽然我们现在可以打开一个浏览器窗口,但你还需要一些额外的模板代码使其看起来更像是各平台原生的应用。 应用程序窗口在每个OS下有不同的行为,Electron将在app中实现这些约定的责任交给开发者们。
一般而言,你可以使用 进程
全局的 platform 属性来专门为某些操作系统运行代码。
关闭所有窗口时退出应用 (Windows & Linux)
在Windows和Linux上,关闭所有窗口通常会完全退出一个应用程序。
为了实现这一点,你需要监听 app
模块的 'window-all-closed' 事件。如果用户不是在 macOS(darwin
) 上运行程序,则调用 app.quit()。
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
如果没有窗口打开则打开一个窗口 (macOS)
当 Linux 和 Windows 应用在没有窗口打开时退出了,macOS 应用通常即使在没有打开任何窗口的情况下也继续运行,并且在没有窗口可用的情况下激活应用时会打开新的窗口。
为了实现这一特性,监听 app
模块的 activate 事件。如果没有任何浏览器窗口是打开的,则调用 createWindow()
方法。
因为窗口无法在 ready
事件前创建,你应当在你的应用初始化后仅监听 activate
事件。 通过在您现有的 whenReady()
回调中附上您的事件监听器来完成这个操作。
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
使用预加载脚本访问渲染器的Node.js
这个步骤我们演示的是输出Electron的版本号和它的依赖项到你的web页面上。
通过 Node 的全局进程对象在主进程中访问这些信息非常简单。 然而,你不能直接在主进程中编辑DOM,因为它无法访问渲染器的document上下文。 它们存在于完全不同的进程!
英文参考文档:Process Model | Electron (electronjs.org)
这时我们要用到预加载脚本。预加载脚本在渲染器进程加载之前加载,并有权访问两个渲染器全局 (例如 window
和 document
) 和 Node.js 环境。
在根目录创建一个名为 preload.js
的新脚本如下:
window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector)
if (element) element.innerText = text
}
for (const dependency of ['chrome', 'node', 'electron']) {
replaceText(`${dependency}-version`, process.versions[dependency])
}
})
上面的代码访问 Node.js的 process.versions
对象,并运行一个基本的 replaceText
辅助函数将版本号插入到 HTML 文档中。
要将此脚本附加到渲染器流程,请在你现有的 BrowserWindow
构造器中将路径中的预加载脚本传入 webPreferences.preload
选项。修改后如下:
const { app, BrowserWindow } = require('electron')
// 在你文件顶部导入 Node.js 的 path 模块
const path = require('node:path')
// 修改已有的 createWindow() 方法
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
}
// ...
这里使用了两个Node.js概念:
使用相对路径的方法在开发和打包时同样有效。
添加你自己的功能
此刻,你可能想知道如何为应用程序添加更多功能。
对于任何与 Web 内容的交互,需要将脚本添加到渲染器进程中。由于渲染器在正常的 Web 环境中运行,因此可以在 index.html 文件的结束标记 </body> 之前添加 <script> 标记,以包含您想要的任意脚本,例如:
<script src="./renderer.js"></script>
renderer.js
中包含的代码可以在接下来使用与前端开发相同的 JavaScript API 和工具。例如使用 webpack 打包并最小化您的代码,或者使用 React 来管理您的用户界面。
完整代码展示
main.js
const { app, BrowserWindow } = require('electron')
// 在你文件顶部导入 Node.js 的 path 模块
const path = require('node:path')
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
preload.js
window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector)
if (element) element.innerText = text
}
for (const dependency of ['chrome', 'node', 'electron']) {
replaceText(`${dependency}-version`, process.versions[dependency])
}
})
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
We are using Node.js <span id="node-version"></span>,
Chromium <span id="chrome-version"></span>,
and Electron <span id="electron-version"></span>.
<script src="./renderer.js"></script>
</body>
</html>
package.json
{
"name": "项目名称",
"version": "1.0.0",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "electron ."
},
"author": "你的名字",
"license": "ISC",
"description": "你的项目描述"
}
效果展示
执行上面的提到的start命令开始程序,结果如下:
快捷键 ctrl+shift+i 打开控制台,如下:
下一篇文章将项目打包成发布版本
标签:createWindow,const,窗口,app,js,BrowserWindow,Electron,World,Hello From: https://blog.csdn.net/weixin_44339850/article/details/140799555