【Electron-playground系统】窗口篇

本文详细探讨了Electron应用中的窗口创建、管理、聚焦与失焦、窗口类型以及窗口间通信等问题,包括如何创建和优化窗口、处理全屏、最大化、最小化、恢复操作,以及主窗口隐藏和恢复的实现。此外,还涵盖了窗口事件触发顺序和一些常见问题的解决方案。
摘要由CSDN通过智能技术生成

窗口篇

作者: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. 优化

问题electronBrowserWindow模块在创建时,如果没有配置 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. 管理窗口

所谓的管理窗口,相当于主进程可以干预窗口多少。

  • 窗口的路由跳转
  • 窗口打开新的窗口
  • 窗口大小、位置等
  • 窗口的显示
  • 窗口类型(无边框窗口、父子窗口)
  • 窗口内 JavaScriptnode 权限,预加载脚本等

这些个方法都存在于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 事件在窗口将要关闭时之前触发,但是在 DOMbeforeunloadunload 事件之前触发。

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

closed 事件在窗口关闭后出触发,但是此时的窗口已经被关闭了,无法通过 event.preventDefault() 来阻止窗口关闭。

win.on
electron-vue是一个将Vue和Electron结合的项目,可以方便地创建多窗口应用程序。下面是一个演示如何在electron-vue中创建多窗口的例子: 1. 首先,在renderer目录下创建一个新的Vue组件,例如`SecondWindow.vue`,用于作为第二个窗口的内容。 ```vue <template> <div> <h1>Second Window</h1> <p>This is the content of the second window.</p> </div> </template> <script> export default { name: 'SecondWindow' } </script> ``` 2. 在`renderer/router/index.js`文件中,添加一个新的路由路径,用于打开第二个窗口。 ```javascript import SecondWindow from '@/components/SecondWindow.vue' // ... const routes = [ // ... { path: '/second', name: 'SecondWindow', component: SecondWindow } ] // ... ``` 3. 在`renderer/App.vue`文件中,添加一个按钮,用于打开第二个窗口。 ```vue <template> <div> <h1>Main Window</h1> <p>This is the content of the main window.</p> <router-link to="/second">Open Second Window</router-link> </div> </template> <script> export default { name: 'App' } </script> ``` 4. 在`renderer/main.js`文件中,添加一个新的窗口创建函数,用于创建第二个窗口。 ```javascript import { createApp } from 'vue' import SecondWindow from './components/SecondWindow.vue' // ... function createSecondWindow() { const secondWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true } }) secondWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL + '#/second') // ... return secondWindow } // ... ``` 5. 在需要打开第二个窗口的地方调用`createSecondWindow`函数。 ```javascript // ... ipcMain.on('open-second-window', () => { const secondWindow = createSecondWindow() // ... }) // ... ``` 现在,你可以通过点击"Open Second Window"按钮来打开第二个窗口,并在第二个窗口中显示"Second Window"的内容。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值