乐趣区

关于html:Electron-Playground-系列窗口篇

作者:Kurosaki

本文次要解说Electron 窗口的 API 和一些在开发之中遇到的问题。

官网文档 尽管比拟全面,然而要想开发一个商用级别的桌面利用必须对整个 Electron API  有较深的理解,能力应答各种需要。

1. 创立窗口

通过 BrowserWindow,来 创立 或者 治理 新的浏览器窗口,每个浏览器窗口都有一个过程来治理。

1.1. 简略创立窗口

const {BrowserWindow} = require('electron');
const win = new BrowserWindow();
win.loadURL('https://github.com');

成果如下:

1.1.2. 优化

问题 electron BrowserWindow 模块在创立时,如果没有配置 show:false,在创立之时就会显示进去,且默认的背景是红色;而后窗口申请 HTML,会呈现视觉闪动。

解决

const {BrowserWindow} = require('electron');
const win = new BrowserWindow({show:false});

win.loadURL('https://github.com');

win.on('ready-to-show',()=>{win.show();
})

两者比照有很大的区别

1.2. 治理窗口

所谓的治理窗口,相当于主过程能够干涉窗口多少。

  • 窗口的路由跳转
  • 窗口关上新的窗口
  • 窗口大小、地位等
  • 窗口的显示
  • 窗口类型(无边框窗口、父子窗口)
  • 窗口内 JavaScript 的 node 权限,预加载脚本等
  • ….

这些个办法都存在于 BrowserWindow 模块中。

1.2.1. 治理利用创立的窗口

BrowserWindow模块在创立窗口时,会返回 窗口实例 ,这些 窗口实例 上有许多性能办法,咱们利用这些办法,管理控制这个窗口。

在这里应用 Map 对象来存储这些 窗口实例

const BrowserWindowsMap = new Map<number, BrowserWindow>()
let mainWindowId: number;

const browserWindows = new BrowserWindow({show:false})
browserWindows.loadURL('https://github.com')
browserWindows.once('ready-to-show', () => {browserWindows.show()
})
BrowserWindowsMap.set(browserWindow.id, browserWindow)
mainWindowId = browserWindow.id  // 记录以后窗口为主窗口

窗口被敞开 ,得把Map 中的实例删除。

browserWindow.on('closed', () => {BrowserWindowsMap?.delete(browserWindowID)
})

1.2.2. 治理用户创立的窗口

主过程能够管制窗口许多行为,这些行为会在后续文章一一列举;以下以主过程管制窗口建设新窗口的行为为例。

应用 new-window 监听新窗口创立

// 创立窗口监听
browserWindow.webContents.on('new-window', (event, url, frameName, disposition) => {/** @params {string} disposition
  *  new-window : window.open 调用
  *  background-tab: command+click
  *  foreground-tab: 右键点击新标签关上或点击 a 标签 target _blank 关上
  * /
})

注:对于 disposition 字段的解释,移步 electron 文档、electron 源码、chrome 源码

扩大new-window

通过试验,并不是所有新窗口的建设,new-window 都能捕捉到的。

以下形式关上的窗口能够被 new-window 事件捕捉到

window.open('https://github.com')
<a href='https://github.com' target='__blank'> 链接 </a>

**
渲染过程中应用 BrowserWindow 创立新窗口,不会被 new-window事件捕捉到
**

const {BrowserWindow} = require('electron').remote
const win = new BrowserWindow()
win.loadURL('https://github.com')

渲染过程拜访 _remote_ _,主过程需配置 enableRemoteModule:true _
应用这种形式同样能够关上一个新的窗口,然而主过程的 new-window 捕获不到。

利用new-window
new-window 管制着窗口新窗口的创立,咱们利用这点,能够做到很多事件;比方链接校验、浏览器关上链接等等。默认浏览器关上链接代码如下:

import {shell} from 'electron'
function openExternal(url: string) {
  const HTTP_REGEXP = /^https?:\/\//
  // 非 http 协定不关上,防止出现自定义协定等导致的平安问题
  if (!HTTP_REGEXP) {return false}
  try {await shell.openExternal(url, options)
    return true
  } catch (error) {console.error('open external error:', error)
    return false
  }
}
// 创立窗口监听
browserWindow.webContents.on('new-window', (event, url, frameName, disposition) => {if (disposition === 'foreground-tab') {
      // 阻止鼠标点击链接
      event.preventDefault()
      openExternal(url)
  }
})

对于 _shell_ _模块,能够查看官网 https://www.electronjs.org/docs/api/shell_
_

1.3. 敞开窗口

**close** 事件和 **closed** 事件
close 事件在窗口将要敞开时之前触发,然而在 DOM 的 beforeunload 和 unload 事件之前触发。

// 窗口注册 close 事件
win.on('close',(event)=>{event.preventDefault()  // 阻止窗口敞开
})

closed 事件在窗口敞开后出触发,然而此时的窗口曾经被敞开了,无奈通过 event.preventDefault() 来阻止窗口敞开。

win.on('closed', handler)

主过程可能敞开窗口的 API 有很多,但都有各自的利弊。

1.3.1. win.close()

对于这个 API 的利弊

  1. 如果以后窗口实例注册并阻止 close 事件,将不会敞开页面,而且也会 阻止计算机敞开(必须手动强制退出);
  2. 敞开页面的服务,如 websocket,下次关上窗口,窗口中的页面会 从新渲染
  3. 通过这个 API 触发的 close 事件在 unloadbeforeunload之前触发,通过这点能够实现 敞开时触发弹窗


残缺代码在 github:electron-playground

  1. 会被 closed 事件捕捉到。

1.3.2. win.destroy()

  1. 强制退出,忽视 close 事件(即:无奈通过 event.preventDefault() 来阻止);
  2. 敞开页面,以及页面内的服务,下次关上窗口,窗口中的页面会从新渲染;
  3. 会被 closed 事件捕捉到。

1.3.3. win.hide()

这个暗藏窗口。

  1. 暗藏窗口,会触发 hideblur事件,同样也是能够通过 event.preventDefault() 来阻止
  2. 只是暗藏窗口,通过win.show(),能够将窗口浮现,并且会放弃原来的窗口,外面的服务也不会挂断

2. 主窗口暗藏和复原

2.1. 主窗口

2.1.1. 为什么须要 主窗口?

一个利用存在着许多的窗口,须要一个窗口作为 主窗口 ,如果该窗口敞开,则意味着整个利用被敞开。
场景:在利用只有一个页面的时,用户点击敞开按钮,不想让整个利用敞开,而是暗藏;
例如:其余的 APP,像微信,QQ 等桌面端。

利用上文中提到的敞开窗口的 API , 咱们实现一个主窗口的暗藏和复原。

革新一下 close 事件

let mainWindowId: number // 用于标记主窗口 id

const browserWindow = new BrowserWindow()

// 记录下主窗口 id
if (!mainWindowId) {mainWindowId = browserWindow.id}

browserWindow.on('close', event => {
  // 如果敞开的是主窗口,阻止
  if (browserWindow.id === mainWindowId) {event.preventDefault()
    browserWindow.hide()}
})

2.1.2. 复原主窗口显示

能暗藏,就能复原。

const mainWindow = BrowserWindowsMap.get(mainWindowId)
if (mainWindow) {mainWindow.restore()
  mainWindow.show()}

**mainWindow.show()** 办法 :性能如其名,就是“show 出窗口”。
为什么要是有 _mainWindow.restore()_ _?_
_windows_ _下如果 _hide_ _之后不调用 _show_ _办法而是只调用 _restore_ _办法就会导致页面挂住不能用

2.1.3. 强制敞开主窗口

有些场景下,可能须要的强制退出,附上代码:

const mainWindow = BrowserWindowsMap.get(mainWindowId)
if (mainWindow) {
  mainWindowId = -1
  mainWindow.close()}

存在的问题

咱们扭转了 Electron 窗口的既定行为,就会有许多场景下会有问题

问题一:因为阻止了 close 事件,导致 关机 时无奈敞开 主窗口,能够应用如下代码

app.on('before-quit', () => {closeMainWindow()
})

在 macOS Linux Windows 下都能够。

问题二:为防止启动 多个利用

app.on('second-instance', () => {const mainWindow = BrowserWindowsMap.get(mainWindowId)
  if (mainWindow) {mainWindow.restore()
    mainWindow.show()}
})

在 macOS Linux Windows 下都能够

问题三:首次启动应用程序、尝试在应用程序已运行时或单击 应用程序 坞站 任务栏图标 时从新激活它

app.on('activate', () => {if (mainWindow) {mainWindow.restore()
    mainWindow.show()}
})

只利用于 macOS

问题四:双击托盘图标 关上APP

tray.on('double-click', () => {if (mainWindow) {mainWindow.restore()
    mainWindow.show()}
})

这样每个环节的代码都有,即可实现,具体代码可参见链接

3. 窗口的聚焦和失焦

3.1. 聚焦

3.1.1. 创立窗口时配置

const {BrowserWindow} = require('electron');
const win = new BrowserWindow();
win.loadURL('https://github.com')

focusable:true  窗口便可聚焦,便能够应用聚焦的 API 
focusable:falseWindows 中设置 focusable: false 也意味着设置了skipTaskbar: true. 在 Linux 中设置 focusable: false 时窗口进行与 wm 交互, 并且窗口将始终置顶;

以下探讨的状况仅为 focusable:true 状况下

const {BrowserWindow} = require('electron');
const win = new BrowserWindow() // focusable:true 为默认配置

列举了一下 API 

3.1.2. 对于聚焦的 API

API 性能
BrowserWindow.getFocusedWindow() 来获取聚焦的窗口
win.isFocused() 判断窗口是否聚焦
win.on('focus',handler) 来监听窗口是否聚焦
win.focus() 手动聚焦窗口

3.1.3. 其余 API 副作用和聚焦无关的:

API 性能
win.show() 显示窗口,并且聚焦于窗口
win.showInactive() 显示窗口,然而不会聚焦于窗口

3.2. 失焦

3.2.1. 对于失焦的api

API 性能
win.blur() 勾销窗口聚焦
win.on('blur',cb) 监听失焦

3.2.2. 其余 api 副作用和失焦无关的:

api 性能
win.hide() 暗藏窗口,并且会触发失焦事件

4. 窗口类型

4.1. 无边框窗口

4.1.1. 形容

无边框窗口是不带外壳(包含窗口边框、工具栏等),只含有网页内容的窗口

4.1.2. 实现

Windows macOS Linux

const {BrowserWindow} = require('electron')
let win = new BrowserWindow({width: 800, height: 600, frame: false})
win.show()

macOS 下,还有不同的实现形式,官网文档

4.1.3. macOS 下独有的无边框

  • 配置titleBarStyle: 'hidden'

返回一个暗藏标题栏的全尺寸内容窗口,在左上角依然有规范的窗口管制按钮(俗称“红绿灯”)

// 创立一个无边框的窗口
const {BrowserWindow} = require('electron')
let win = new BrowserWindow({titleBarStyle: 'hidden'})
win.show()

成果如下:

  • 配置titleBarStyle: 'hiddenInset'

返回一个另一种暗藏了标题栏的窗口,其中管制按钮到窗口边框的间隔更大。

// 创立一个无边框的窗口
const {BrowserWindow} = require('electron')
let win = new BrowserWindow({titleBarStyle: 'hiddenInset'})
win.show()

成果如下:

配置titleBarStyle: 'customButtonsOnHover'

成果如下:

4.1.4. 窗口顶部无奈拖拽的问题

尽管无边框窗口,很好看,能够自定义 title;然而扭转了 Electron 窗口顶部的默认行为,就须要应用代码来兼容它,实现其原来承当的性能。


呈现上述情况,是因为在默认状况下, 无边框窗口是不可拖拽的。应用程序须要在 CSS 中指定 -webkit-app-region: drag 来通知 Electron 哪些区域是可拖拽的(如操作系统的规范标题栏),在可拖拽区域外部应用 -webkit-app-region: no-drag 则能够将其中局部区域排除。请留神, 以后只反对矩形形态。残缺文档

应用 -webkit-app-region: drag 来实现拖拽,然而会导致外部的click 事件生效。这个时候能够将须要 click 元素设置为-webkit-app-region: no-drag。具体的细节 Electron 的 issues

为了不影响窗口内的业务代码,这里拖拽的代码,应该在 preload 触发。

preload 代码运行,在窗口代码运行之前

外围代码:

// 在顶部插入一个能够挪动的 dom
function initTopDrag() {const topDiv = document.createElement('div') // 创立节点
  topDiv.style.position = 'fixed' // 始终在顶部
  topDiv.style.top = '0'
  topDiv.style.left = '0'
  topDiv.style.height = '20px' // 顶部 20px 才可拖动
  topDiv.style.width = '100%' // 宽度 100%
  topDiv.style.zIndex = '9999' // 悬浮于最外层
  topDiv.style.pointerEvents = 'none' // 用于点击穿透
  // @ts-ignore
  topDiv.style['-webkit-user-select'] = 'none' // 禁止抉择文字
  // @ts-ignore
  topDiv.style['-webkit-app-region'] = 'drag' // 拖动
  document.body.appendChild(topDiv) // 增加节点
}

window.addEventListener('DOMContentLoaded', function onDOMContentLoaded() {initTopDrag()
})

在创立窗口时援用 preload 即可

const path = require('path')
const {BrowserWindow} = require('electron')

const BaseWebPreferences = {
  nodeIntegration: true,
  preload: path.resolve(__dirname, './windowType.js'), // 这里援用 preload.js 门路
}

// 主窗口代码
const win = new BrowserWindow({webPreferences: BaseWebPreferences, frame: false, titleBarStyle: 'hiddenInset'})
win.loadURL('https://github.com')

便可实现窗口顶部拖拽

tips: 如果窗口关上了 _devtools_ _,窗口也是能够拖拽的,只不过这个拖拽体验不好_

4.2. 父子窗口

所谓的父子窗口,就是子窗口永远在父窗口之上,只有子窗口存在,哪怕地位不在父窗口上方,都是无奈操作父窗口

const {BrowserWindow} = require('electron')

let top = new BrowserWindow()
let child = new BrowserWindow({parent: top})
child.show()
top.show()

窗口之间通信 章节中介绍到父子窗口之间的通信;通过 getParentWindow 拿到父窗口的 类 BrowserWindowProxy,通过 win.postMessage(message,targetOrigin) 实现通信

4.3. 模态窗口

模态窗口也是一种父子窗口,只不过展示会有不同

const {BrowserWindow} = require('electron')

let top = new BrowserWindow()
let child = new BrowserWindow({parent: top, modal: true, show: false})
child.loadURL('https://github.com')
child.once('ready-to-show', () => {child.show()
})

5. 窗口之间的通信

实现窗口通信必须不影响窗口内的业务代码,jdk 等的注入

5.1. 主过程干涉形式

主过程是能够干涉渲染过程生成新的窗口的,只须要在创立窗口时,webContents 监听 new-window

import path from 'path'
import {PRELOAD_FILE} from 'app/config'
import {browserWindow} from 'electron';

const BaseWebPreferences: Electron.BrowserWindowConstructorOptions['webPreferences'] = {
  nodeIntegration: true,
  webSecurity: false,
  preload: path.resolve(__dirname, PRELOAD_FILE),
}


// 创立窗口监听
browserWindow.webContents.on('new-window', (event, url, frameName, disposition) => {event.preventDefault()
    // 在通过 BrowserWindow 创立窗口
    const win = new BrowserWindow({ 
      show:false, 
      webPreferences: {
        ...BaseWebPreferences,
        additionalArguments:[`--parentWindow=${browserWindow.id}`] // 把父窗口的 id 传过来
      } 
    });
    win.loadURl(url);
    win.once('ready-to-show',()=>{win.show()
    })
})

preload.js  文件 window.process.argv,便能拿到父窗口的 id,window.process.argv 是一个字符串数组,能够应用 yargs 来解析

preload.js  代码

import {argv} from 'yargs'
console.log(argv);


拿到了父窗口的 id,封装一下通信代码,挂载到 window 上

/**
 * 这个是用于窗口通信例子的 preload,* preload 执行程序在窗口 js 执行程序之前
 */
import {ipcRenderer, remote} from 'electron'
const {argv} = require('yargs')

const {BrowserWindow} = remote

// 父窗口监听子窗口事件
ipcRenderer.on('communication-to-parent', (event, msg) => {alert(msg)
})

const {parentWindowId} = argv
if (parentWindowId !== 'undefined') {const parentWindow = BrowserWindow.fromId(parentWindowId as number)
  // 挂载到 window
  // @ts-ignore
  window.send = (params: any) => {parentWindow.webContents.send('communication-to-parent', params)
  }
}

利用一下试试看:

这种办法能够实现通信,然而太麻烦了。

5.2. 父子窗口通信

和主过程干涉,通过 ipc 通信形式差不多,只是利用父子窗口这点,不必通过 additionalArguments 传递父窗口id,在子窗口通过window.parent,就能够拿到父窗口

browserWindow.webContents.on('new-window', (event, url, frameName, disposition) => {event.preventDefault()
      
    // 在通过 BrowserWindow 创立窗口
    const win = new BrowserWindow({ 
        show:false, 
        webPreferences:BaseWebPreferences,
        parent:browserWindow // 增加父窗口
      });
    win.loadURl(url);
    win.once('ready-to-show',()=>{win.show()
    })
    
})

弊病:子窗口永远在父窗口之上。

const path = require('path')
const {BrowserWindow} = require('electron')

const BaseWebPreferences = {
  // // 集成 node
  nodeIntegration: true,
  // // 禁用同源策略
  // webSecurity: false,
  // 预加载脚本 通过相对地址注入
  preload: path.resolve(__dirname, './communication2.js'),
}

// 主窗口代码
const parent = new BrowserWindow({webPreferences: BaseWebPreferences, left: 100, top: 0})
parent.loadURL('file:///' + path.resolve(__dirname, '../playground/index.html#/demo/communication-part2/main'),
)
parent.webContents.on('new-window', (event, url, frameName, disposition) => {
  // 阻止默认事件
  event.preventDefault()
  // 在通过 BrowserWindow 创立窗口
  // 子窗口代码
  const son = new BrowserWindow({
    webPreferences: BaseWebPreferences,
    parent,
    width: 400,
    height: 400,
    alwaysOnTop: false,
  })
  // son.webContents.openDevTools();
  son.loadURL(
    'file:///' +
      path.resolve(__dirname, '../playground/index.html#/demo/communication-part2/client'),
  )
})

preload.js

import {remote, ipcRenderer} from 'electron'

// 父窗口监听子窗口事件
ipcRenderer.on('communication-to-parent', (event, msg) => {alert(msg)
})

const parentWindow = remote.getCurrentWindow().getParentWindow()
// @ts-ignore
window.sendToParent = (params: any) =>
  parentWindow.webContents.send('communication-to-parent', params)


然而必须得是父子窗口,有弊病。

5.3. 应用window.open

终极办法

web 端,应用 window.open  会返回一个 windowObjectReference,通过这个办法能够实现 postMessage;然而在 Electron 端,把 window.open 办法从新定义了;应用 window.open 创立一个新窗口时会返回一个 BrowserWindowProxy对象,并提供一个无限性能的子窗口.
MDN 文档 Electron 文档

const  BrowserWindowProxy = window.open('https://github.com', '_blank', 'nodeIntegration=no')
BrowserWindowProxy.postMessage(message, targetOrigin)

代码精简,且须要的性能,即合乎 BrowserWindow(options) 中 options 配置的,都能够应用 window.open 配置。

6. 全屏、最大化、最小化、复原

6.1. 全屏

6.1.1. 创立时进入全屏

配置new BrowserWindow({fullscreen:true})

const {BrowserWindow} = require('electron')
const win = new BrowserWindow({fullscreen:true,fullscreenable:true})
win.loadURL('https://github.com')

6.1.2. 应用 API 进入全屏

确保以后窗口的 fullscreenable:true,以下API 能力应用

  1. win.setFullScreen(flag),设置全屏状态;
  2. win.setSimpleFullScreen(flag)macOS下独有,设置简略全屏。

6.1.3. 全屏状态的获取

  1. win.fullScreen,来判断以后窗口是否全屏;
  2. win.isFullScreen()macOS独有;
  3. win.isSimpleFullScreen()macOS独有。

6.1.4. 全屏事件的监听

  1. rezise 调整窗口大小后触发;
  2. enter-full-screen 窗口进入全屏状态时触发;
  3. leave-full-screen 窗口来到全屏状态时触发;
  4. enter-html-full-screen 窗口进入由 HTML API 触发的全屏状态时触发;
  5. leave-html-full-screen 窗口来到由 HTML API 触发的全屏状态时触发。

6.1.5. HTML API无奈和窗口联动问题

const path = require('path')
const {BrowserWindow} = require('electron')
const BaseWebPreferences = { 
    nodeIntegration: true,
    preload: path.resolve(__dirname, './fullScreen.js'), 
};
const win = new BrowserWindow({webPreferences: BaseWebPreferences})
win.loadURL('file:///' + path.resolve(__dirname, '../playground/index.html#/demo/full-screen'))

应用按钮全屏和退出全屏是能够的,然而先点击左上角???? 全屏,再应用按钮退出全屏,是不行的。因为无奈晓得以后的状态是全屏,还是不是全屏。

解决办法:,将 win.setFullScreen(flag) 办法挂载到窗口的 window
加载这样一段 preload.js 代码即可

import {remote} from 'electron'

const setFullScreen = remote.getCurrentWindow().setFullScreen
const isFullScreen = remote.getCurrentWindow().isFullScreen

window.setFullScreen = setFullScreen
window.isFullScreen = isFullScreen

setFullScreen 文档 https://www.electronjs.org/docs/api/browser-window#winsetfullscreenflag isFullScreen 文档https://www.electronjs.org/docs/api/browser-window#winisfullscreen

6.2. 最大化、最小化

6.2.1. 创立窗口配置

残缺 API 文档

const {BrowserWindow} = require('electron')
const win = new BrowserWindow({minWidth:300,minHeight:300,maxWidth:500,maxHeight:500,width:600,height:600})
win.loadURL('https://github.com')

当应用 minWidth/maxWidth/minHeight/maxHeight 设置最小或最大窗口大小时, 它只限度用户。它不会阻止您将不合乎大小限度的值传递给 setBounds/setSizeBrowserWindow 的构造函数。

6.2.2. 相干事件

事件名称 触发条件
maximize 窗口最大化时触发
unmaximize 当窗口从最大化状态退出时触发
minimize 窗口最小化时触发
restore 当窗口从最小化状态复原时触发

6.2.3. 相干状态 API

  1. win.minimizable 窗口是否能够最小化
  2. win.maximizable 窗口是否能够最大化
  3. win.isMaximized() 是否最大化
  4. win.isMinimized() 是否最小化

6.2.4. 管制 API

  1. win.maximize() 使窗口最大化
  2. win.unmaximize() 退出最大化
  3. win.minimize() 使窗口最小化
  4. win.unminimize() 退出最小化

6.3. 窗口复原

win.restore() 将窗口从最小化状态复原到以前的状态。在后面的例子 主窗口暗藏和复原也有用到这个 api

7. 窗口各事件触发程序

7.1. 窗口加载时

BrowserWindow 实例:即 new BrowserWindow() 返回的实例对象
webContents:即 BrowserWindow 实例中的 webContents 对象
webPreferences: 即 new BrowserWindow(options) 中 options 的 webPreferences 配置对象

从上到下,顺次执行

环境 事件 触发机会
webPreferences 的 preload 在页面运行其余脚本之前事后加载指定的脚本 无论页面是否集成 Node, 此脚本都能够拜访所有 Node API 脚本门路为文件的绝对路径。
webContents did-start-loading 当 tab 中的旋转指针(spinner)开始旋转时,就会触发该事件
webContents did-start-navigation 当窗口开始导航是,触发该事件
窗口中的JavaScript DOMContentLoaded 初始的 HTML 文档被齐全加载和解析实现
窗口中的JavaScript load 页面资源全副加载实现之时
BrowserWindow实例 show 窗口显示时触发时
webContents did-frame-navigate frame导航完结时时
webContents did-navigate main frame导航完结时时
BrowserWindow实例 page-title-updated 文档更改题目时触发
webContents page-title-updated 文档更改题目时触发
webContents dom-ready 一个框架中的文本加载实现后触发该事件
webContents did-frame-finish-load 当框架实现导航(navigation)时触发
webContents did-finish-load 导航实现时触发,即选项卡的旋转器将进行旋转
webContents did-stop-loading 当 tab 中的旋转指针(spinner)完结旋转时,就会触发该事件

7.2. 窗口加载结束,用户触发事件(不包含 resize 和 move)

事件 作用
page-title-updated 文档更改题目时触发
blur 当窗口失去焦点时触发
focus 当窗口取得焦点时触发
hide 窗口暗藏
show 窗口显示
maximize 窗口最大化时触发(mac 是双击 title)
unmaximize 当窗口从最大化状态退出时触发
enter-full-screen 窗口进入全屏状态时触发
leave-full-screen 窗口来到全屏状态时触发
enter-html-full-screen 窗口进入由 HTML API 触发的全屏状态时触发
leave-html-full-screen 窗口来到由 HTML API 触发的全屏状态时触发
always-on-top-changed 设置或勾销设置窗口总是在其余窗口的顶部显示时触发。
app-command window linux独有

7.3. 用户挪动窗口

  1. 挪动窗口之前 will-move
  2. 挪动窗口中 move
  3. 挪动之后 moved

7.4. 用户扭转窗口大小

  1. 扭转之前 will-resize
  2. 扭转之后 resize

7.5. 窗口的内容异样事件(webContent事件)

事件名 谬误类型
unresponsive 网页变得未响应时触发
responsive 未响应的页面变成响应时触发
did-fail-load 加载失败,错误码
did-fail-provisional-load 页面加载过程中,执行了window.stop()
did-frame-finish-load
crashed 渲染过程解体或被完结时触发
render-process-gone 渲染过程意外失败时收回
plugin-crashed 有插件过程解体时触发
certificate-error 证书的链接验证失败
preload-error preload.js抛出谬误

7.6. 窗口敞开(包含意外敞开)

  • 敞开之前:触发主过程中注册的 close  事件
  • 窗口内的 JavaScript  执行 window.onbeforeunload 
  • 窗口内的 JavaScript  执行 window.onunload 
  • 敞开之后:触发主过程中注册的 closed  事件

对 Electron 感兴趣?请关注咱们的开源我的项目 Electron Playground,带你极速上手 Electron。

咱们每周五会精选一些有意思的文章和音讯和大家分享,来掘金关注咱们的 晓前端周刊。


咱们是好将来 · 晓黑板前端技术团队。
咱们会常常与大家分享最新最酷的行业技术常识。
欢送来 知乎、掘金、Segmentfault、CSDN、简书、开源中国、博客园 关注咱们。

退出移动版