打开一个新窗口并加载 URL。
当调用 window.open 以在网页中创建新窗口时,将为url 创建一个新的BrowserWindow 实例,并返回一个代理至 window.open 以让页面对其进行有限的控制。
window.open(url,frameName,features)
Returns BrowserWindowProxy - 创建一个新窗口,并返回一个 BrowserWindowProxy 类的实例。
features 字符串遵循标准浏览器的格式,但每个 feature 必须是BrowserWindow 选项中的字段。 These are the features you can set via features string: zoomFactor, nodeIntegration, preload, javascript, contextIsolation, webviewTag.
例如:
window.open('https://github.com', '_blank', 'nodeIntegration=no')
注意:
将消息发送给指定来源的父窗口,如果未指定来源则发送给*,即所有窗口。
使用 Chrome 的 window.open()
如果要使用 Chrome 的内置 window.open(),请在 webPreferences 选项中将 nativeWindowOpen 设置为 true。
原生 window.open () 允许同步打开窗口, 因此可以方便的选择是对话框还是首选项窗口。
该选项也可以设置在
"nativeWindowOpen=yes">
BrowserWindow的创建可通过WebContents 的 new-window事件进行定制 。
- // main process
- const mainWindow = new BrowserWindow({
- width: 800,
- height: 600,
- webPreferences: {
- nativeWindowOpen: true
- }
- })
- mainWindow.webContents.on('new-window', (event, url, frameName, disposition, options, additionalFeatures) => {
- if (frameName === 'modal') {
- // open window as modal
- event.preventDefault()
- Object.assign(options, {
- modal: true,
- parent: mainWindow,
- width: 100,
- height: 100
- })
- event.newGuest = new BrowserWindow(options)
- }
- })
-
- // renderer process (mainWindow)
- const modal = window.open('', 'modal')
- modal.document.write('
Hello
')
例: 打开一个子窗口并向父窗口传递消息
主线程脚本
main.js
- //为了管理应用程序的生命周期事件以及创建和控制浏览器窗口,您从 electron 包导入了 app 和 BrowserWindow 模块 。
- const { app, BrowserWindow } = require('electron')
-
- //在此之后,你定义了一个创建 新的浏览窗口的函数并将 nodeIntegration 设置为 true,将 index.html 文件加载到窗口中(第 12 行,稍后我们将讨论该文件)
- function createWindow () {
- const win = new BrowserWindow({
- width: 800,
- height: 600,
- webPreferences: {
- //开启webview 标签 Electron >= 5 后需要开启
- webviewTag:true,
- nodeIntegration: true
- }
- })
-
- win.loadFile('index.html')
- }
-
- //你通过调用 createWindow方法,在 electron app 第一次被初始化时创建了一个新的窗口。
- app.whenReady().then(createWindow)
-
- //您添加了一个新的侦听器,当应用程序不再有任何打开窗口时试图退出。 由于操作系统的 窗口管理行为 ,此监听器在 macOS 上是禁止操作的
- app.on('window-all-closed', () => {
- if (process.platform !== 'darwin') {
- app.quit()
- }
- })
-
- //您添加一个新的侦听器,只有当应用程序激活后没有可见窗口时,才能创建新的浏览器窗口。 例如,在首次启动应用程序后或重启运行中的应用程序
- app.on('activate', () => {
- if (BrowserWindow.getAllWindows().length === 0) {
- createWindow()
- }
- })
主窗口
index.html
- DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Hello World!title>
- <style>
- .for_file_drag{
- width: 100%;
- height: 400px;
- background-color: pink;
- }
- style>
- head>
- <body>
- <h1>window open 函数h1>
- <button onclick="openChildWindow()">点击弹出子窗口button>
- body>
- <script>
- //打开当前目录child.html 为子窗口
- function openChildWindow() {
- window.open('child.html', '_blank')
- }
-
- //添加消息监听
- window.addEventListener('message', (e) => {
- console.log('接受到的消息:'+ e.data);
- });
- script>
- html>
子窗口
child.html
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>子窗口title>
- head>
- <body>
- <h1>这是子窗口h1>
- <button onclick="sendParentMsg()">向父窗口回传信息button>
- body>
- <script>
- function sendParentMsg() {
- window.opener.postMessage('test');
- }
- script>
- html>
效果

例:打开子窗口的另一种方式
main.js
- const { app, BrowserWindow } = require('electron')
-
- function createWindow() {
- const win = new BrowserWindow({
- width: 800,
- height: 600,
- show: false,
- // frame: true,
- // autoHideMenuBar: true,
- title: "Samve",
- // icon: "",
- webPreferences: {
- nodeIntegration: true,
- contextIsolation: false,
- enableRemoteModule: true
- }
- })
-
- require('@electron/remote/main').initialize()
- require("@electron/remote/main").enable(win.webContents)
-
- win.loadFile('index.html')
-
- win.on("ready-to-show", function(){
- win.show();
- })
- }
-
- app.on("ready", function(){
- createWindow();
- })
-
- app.on("window-all-closed", function(){
- app.quit();
- })
index.html
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>title>
- head>
- <body>
- <h1>父窗口h1>
- <div><button id="btn">打开button>div>
- <script src="render.js">script>
- body>
- html>
render.js
- const remote = require("@electron/remote")
-
- window.addEventListener("DOMContentLoaded", () => {
- const oBtn = document.getElementById("btn");
- oBtn.addEventListener("click", () => {
- let subWin = new remote.BrowserWindow({
- parent: remote.getCurrentWindow(),
- width: 500,
- height: 300
- })
-
- console.log("loadFile");
-
- subWin.loadFile("sub.html");
-
- subWin.on("close", () => {
- subWin = null;
- })
- })
- })
sub.html
- DOCTYPE html>
-
-
-
-
Document - 子页面
例:在父窗口中控制关闭子窗口
在第一个例子中演示打开窗口并回传信息,那如果要在主窗口中关闭子窗口怎么做呢?这时候就要用
BowserWindowProxy对象了
Returns BrowserWindowProxy - 创建一个新窗口,并返回一个
BrowserWindowProxy类的实例。
这个对象是创建新窗口返回的
api参考:
https://www.electronjs.org/docs/api/browser-window-proxy
将上面的主窗口代码稍微改下
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Hello World!title>
- <style>
- .for_file_drag{
- width: 100%;
- height: 400px;
- background-color: pink;
- }
- style>
- head>
- <body>
- <h1>window open 函数h1>
- <button onclick="openChildWindow()">点击弹出子窗口button>
- <button onclick="closeChildWindow()">点击关闭子窗口button>
- body>
- <script>
- let childBowserWindowProxy = null;
-
- //打开当前目录child.html 为子窗口
- function openChildWindow() {
- childBowserWindowProxy = window.open('child.html', '_blank')
- }
-
- //关闭当前窗口
- function closeChildWindow(){
- childBowserWindowProxy.close();
- }
-
- //添加消息监听
- window.addEventListener('message', (e) => {
- console.log('接受到的消息:'+ e.data);
- });
-
-
- script>
- html>

在第二例子中,我发现不管我点击几次弹出子窗口,app只会弹出一个子窗口,这是为什么呢?
经过一阵研究发现,只要window.open 的第二个参数也就是frameName参数一致,它就会始终只有一个
例如这种只会有一个
- //打开当前目录child.html 为子窗口
- function openChildWindow() {
- childBowserWindowProxy = window.open('child.html', '_blank')
- }
但是这种会点击几个创建几个
- //打开当前目录child.html 为子窗口
- function openChildWindow() {
- childBowserWindowProxy = window.open('child.html', '_blank'+ new Date().getTime())
- }
父子窗口(Mac OS X和Windows有一定差异)
子窗口相当于父窗口的悬浮窗口
Mac OS X和Windows的父子窗口的区别是:
main.js
-
- /**
- * 父子窗口(Mac OS X和Windows有一定差异)
- * 1、子窗口总是在父窗口之上
- * 2、如果父窗口关闭,子窗口自动关闭
- *
- * 子窗口相当于父窗口的悬浮窗口
- * Mac OS X和Windows的父子窗口的区别是:
- * 在Mac OS X下,移动父窗口,子窗口会随着父窗口移动
- * 在Windows下子窗口不会移动
- */
-
- const {
- app,
- BrowserWindow
- } = require('electron')
-
- function createWindow() {
- const win = new BrowserWindow({
- width: 800,
- height: 600,
- // frame: false,
- webPreferences: {
- // preload: path.join(__dirname, 'preload.js'),
- nodeIntegration: true,
- contextIsolation: false
- }
- })
-
- win.loadFile('index.html')
-
- childWin = new BrowserWindow({
- parent: win, width: 400, height: 300,
- //module:true
- });
-
- childWin.loadFile('child.html');
- }
-
- app.whenReady().then(() => {
- createWindow()
-
- app.on('activate', () => {
- if (BrowserWindow.getAllWindows().length === 0) {
- createWindow()
- }
- })
- })
-
- app.on('window-all-closed', () => {
- if (process.platform !== 'darwin') {
- app.quit()
- }
- })
index.html
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Hello World!title>
- <style>
- .for_file_drag{
- width: 100%;
- height: 400px;
- background-color: pink;
- }
- style>
- head>
- <body>
- <h1>父窗口h1>
- body>
- html>
child.html
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>子窗口title>
- head>
- <body>
- <h1>这是子窗口h1>
- body>
- html>
模态窗口是指禁用父窗口的子窗口,也就是说,处于模态的子窗口显示后,无法使用父窗口,直到子窗口关闭。
1、模态窗口需要是另外一个窗口;
2、一旦模态窗口显示,父窗口将无法使用。
modal=true
Mac OS X 和Windows的模态窗口差异:
1、模态窗口在Mac OS X下会隐藏的标题栏,只能通过close方法关闭模态子窗口
在Windows下,模态子窗口仍然会显示菜单和标题栏
2、在Mac OS X下,模态子窗口显示后,父窗口仍然可以拖动,但无法关闭,在Windows下,模态子窗口显示后父窗口无法拖动
应用:主要用于桌面应用的对话框显示,如设置对话框、打开对话框。
代码示例,同父子窗口,只是子窗口多了一个modal属性,其值为true。