electron主进程如何拦截关闭事件?关闭事件触发顺序
发布于 作者:苏南大叔 来源:程序如此灵动~
总是有小伙伴喜欢拦截窗体关闭事件,然后做出些不太合乎常规的操作。那么,本文中,苏南大叔要探讨的就是electron关闭事件中,都会触发哪些分事件呢?又如何进行相关事件拦截呢?本文没有标准答案,具体在哪个事件里面进行拦截,大家请根据自己的实际情况进行选择。

本文测试环境:electron@4.0.1,win10+mac+centos。本文致力于在主进程层面上,解决拦截关闭事件的问题。事实上,在渲染进程层面上,也是可以做到类似效果的。不过,渲染进程层面的解决方案并不在本文的讨论范围之内。敬请期待后续文章。
基本概念
传统意义上的关闭,在electron中大体可以分为两个概念,分别是:关闭窗体、退出程序。一定要注意:这是两个不同的概念。窗体可以有很多个的,而主程序体一般来说,只有一个。
- 对于非
mac系统来说,比如win系统(centos系统)来说,正常的程序体关闭最后一个窗体的时候,就是程序退出了。 - 但是在
mac系统下,并不是这样的,关闭最后一个窗体,也不会触发程序体的退出。除非明确的指出要退出程序,才会触发进一步的程序退出事件。
如果能够理解上述概念的话,本文的内容就比较好理解了:
点击关闭按钮后,首先触发窗体的关闭事件,然后触发所有窗体的关闭事件,最后触发程序的退出事件。流程就是这样的,而且上述三组事件里面,都还有小的分事件。所以,具体您需要在哪个位置进行拦截,这都是需要您自己决定的。
窗体关闭事件
下面的代码中,假设主窗体名字叫做mainWindow。那么,先后触发的相关事件是close,closed。苏南大叔理解的事件先后顺序为:close=》窗体关闭=》closed。
mainWindow.on('close', function (event) {});
mainWindow.on('closed', function (event) {});需要注意的是:如果是单独的最后一个窗口的话,closed事件之前,还会触发一个app级别的window-all-closed事件,如果不是mac平台的话,还会在window-all-closed里面,还会触发before-quit和will-quit。但是before-quit和will-quit,会发生在window-all-closed和closed之后。
所有窗体的关闭事件
如果关闭的是最后一个窗体,那么在当前窗体的closed事件发生之前,会自动触发一个app层级上的window-all-closed事件。
app.on('window-all-closed', function (event) {});程序退出事件
如果是非mac系统,如果关闭的是最后一个窗体,默认情况下,就会连带触发app级别的退出事件。而对于mac,需要右键选择退出,才会触发这个app级别的退出事件。先触发before-quit,然后触发 will-quit,最后才真正的quit行为。
app.on('before-quit', (event) => {});
app.on('will-quit', (event) => {});注意:对于最后一个窗体关闭的时候,是否会触发app的quit。实际上是你的代码里面写的,也就是说是人为可控的,手工遵守约定俗成的规矩而已,你懂的。
您可以查找一下主进程代码中,是否存在下面的类似代码:
app.on('window-all-closed', function (event) {
//...
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})上述代码的意思就是:如果不是darwin系统,那么所有窗口关闭的时候,就直接触发app.quit(),也就是大家所熟悉的后续流程了。
event.preventDefault()
上述各个事件中,不管是mainWindow的close/closed。还是app的window-all-closed,甚至before-quit/will-quit/quit,都有个参数叫做event。
那么,如果您要阻拦对应的事件的话,在事件体代码中的合适位置,写入下面的语句即可:
event.preventDefault()
至于这些事件的先后顺序,苏南大叔是通过打印时间戳,来获得直观的感受的,详情见上图即可。
总结
这里,推荐大家阅读一下下面这篇有关electron的messagebox的说明文章,再结合preventDefault(),最后再选择一个合适的事件切入点,就可以组合出大家想要的效果了。
更多electron相关经验文字,请点击苏南大叔的文章: