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
相关经验文字,请点击苏南大叔的文章:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。