大家好,欢迎来到IT知识分享网。
用 Electron 开发应用,会遇到需要多个窗口同时工作的情况。我们有两种方法实现多窗口,一种是主进程中 create new BrowserWindow,另一种是从渲染进程打开新窗口。
create new BrowserWindow
新建一个浏览器窗口,这种方式是很容易理解和掌握的,因为使用Electron开发,创建第一个窗口就是用的这种方式,当需要新的窗口时,再次调用 new BrowserWindow。
从渲染进程打开新窗口
- 如果属性中包含 target=_blank,单击链接或提交表单即可创建
- 在 JavaScript 中调用 window.open()
对于同源内容,将在同一进程中创建新窗口,使父窗口能够直接访问子窗口。 这对于充当偏好面板或父窗口直接渲染子窗口的应用,是非常有用的,就像它是 父窗口中的 div 一样。 这与浏览器中的行为相同。
Electron 在内部将原生 Chrome Window 和 BrowserWindow 关联。 当在主进程通过 webContents.setWindowOpenHandler() 为渲染进程创建一个 BrowserWindow 时,你可以使用所有自定义的能力。
官网的描述很有趣,提到了父窗口直接渲染子窗口,我思索半天,大概指的是childWindow.document.write(‘<h1>Hello</h1>’),如果是的话那作用也不太大。
webContents.setWindowOpenHandler()
主窗口可以通过这个方法控制打开新窗口的行为,例如返回{ action: ‘deny’ } 可以阻止打开新窗口,返回 { action: ‘allow’, overrideBrowserWindowOptions: { … } } 可以在打开新窗口的时候传入参数,这个属性名叫 overrideBrowserWindowOptions, 不是覆盖 opener 的属性,而是调用 window.open 时传入的参数features ,所以preload脚本还是要传的,否则脚本不会执行,那 contextBridge 不会在新窗口中注入接口。
新窗口打开后,app上的 browser-window-created 事件会触发,一个新的BrowserWindow对象也会创建出来。
一点区别
两种方式创建新窗口,最大的区别是:渲染进程创建的窗口,在前端可以通过 childWindow 和 window.opener直接互相访问。
窗口间通信
- 使用IPC进程间通信,利用主进程转发消息实现。
- childWindow 和 window.opener直接互相访问,需要从渲染进程打开新窗口,并且同源。
- 页面通信,例如postMessage,channel,storage等。
结合TypeScript
我目前用的是window.open的方式,一个是接口调用简单,另一个是占用的资源会节约一些。但是这里有个问题, childWindow是Window类型,但opener 是 any 类型,会影响类型推断,我这里做了类型收缩。
interface MainAPI{ hello?:"world", sayHi?:(msg: any)=>string, } interface MainRenderer { electronAPI : electronAPI MainAPI:MainAPI, } const oper = (window.opener as MainRenderer)
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/159041.html