我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

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

苏南大叔:electron主进程如何拦截关闭事件?关闭事件触发顺序 - electron-quit
electron主进程如何拦截关闭事件?关闭事件触发顺序(图2-1)

本文测试环境:electron@4.0.1win10+mac+centos。本文致力于在主进程层面上,解决拦截关闭事件的问题。事实上,在渲染进程层面上,也是可以做到类似效果的。不过,渲染进程层面的解决方案并不在本文的讨论范围之内。敬请期待后续文章。

基本概念

传统意义上的关闭,在electron中大体可以分为两个概念,分别是:关闭窗体、退出程序。一定要注意:这是两个不同的概念。窗体可以有很多个的,而主程序体一般来说,只有一个。

  • 对于非mac系统来说,比如win系统(centos系统)来说,正常的程序体关闭最后一个窗体的时候,就是程序退出了。
  • 但是在mac系统下,并不是这样的,关闭最后一个窗体,也不会触发程序体的退出。除非明确的指出要退出程序,才会触发进一步的程序退出事件。

如果能够理解上述概念的话,本文的内容就比较好理解了:
点击关闭按钮后,首先触发窗体的关闭事件,然后触发所有窗体的关闭事件,最后触发程序的退出事件。流程就是这样的,而且上述三组事件里面,都还有小的分事件。所以,具体您需要在哪个位置进行拦截,这都是需要您自己决定的。

窗体关闭事件

下面的代码中,假设主窗体名字叫做mainWindow。那么,先后触发的相关事件是closeclosed。苏南大叔理解的事件先后顺序为:close=》窗体关闭=》closed

mainWindow.on('close', function (event) {});
mainWindow.on('closed', function (event) {});

需要注意的是:如果是单独的最后一个窗口的话,closed事件之前,还会触发一个app级别的window-all-closed事件,如果不是mac平台的话,还会在window-all-closed里面,还会触发before-quitwill-quit。但是before-quitwill-quit,会发生在window-all-closedclosed之后。

所有窗体的关闭事件

如果关闭的是最后一个窗体,那么在当前窗体的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) => {});

注意:对于最后一个窗体关闭的时候,是否会触发appquit。实际上是你的代码里面写的,也就是说是人为可控的,手工遵守约定俗成的规矩而已,你懂的。

您可以查找一下主进程代码中,是否存在下面的类似代码:

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()

上述各个事件中,不管是mainWindowclose/closed。还是appwindow-all-closed,甚至before-quit/will-quit/quit,都有个参数叫做event

那么,如果您要阻拦对应的事件的话,在事件体代码中的合适位置,写入下面的语句即可:

event.preventDefault()

苏南大叔:electron主进程如何拦截关闭事件?关闭事件触发顺序 - event_return_false
electron主进程如何拦截关闭事件?关闭事件触发顺序(图2-2)

至于这些事件的先后顺序,苏南大叔是通过打印时间戳,来获得直观的感受的,详情见上图即可。

总结

这里,推荐大家阅读一下下面这篇有关electronmessagebox的说明文章,再结合preventDefault(),最后再选择一个合适的事件切入点,就可以组合出大家想要的效果了。

更多electron相关经验文字,请点击苏南大叔的文章:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   electron