官方文檔:
https://www.electronjs.org/docs/api/window-open
https://www.electronjs.org/docs/api/browser-window-proxy
window.open 函數
打開一個新窗口並加載 URL。
當調用 window.open
以在網頁中創建新窗口時,將為url
創建一個新的BrowserWindow 實例,並返回一個代理至 window.open
以讓頁面對其進行有限的控制。
The proxy has limited standard functionality implemented to be compatible with traditional web pages. For full control of the new window you should create a BrowserWindow
directly.
The newly created BrowserWindow
will inherit the parent window's options by default. To override inherited options you can set them in the features
string.
window.open(url,frameName,features)
url
StringframeName
String(可選)features
String(可選)
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')
注意:
- 如果在父窗口中禁用了 Node integration, 則在打開的
window
中將始終被禁用。 - 如果在父窗口中啟用了上下文隔離, 則在打開的
window
中將始終被啟用。 - 父窗口禁用 Javascript,打開的
window
中將被始終禁用 features
中給定的非標准特性 (不由 Chromium 或 Electron 處理) 將被傳遞到additionalFeatures
參數中的任何已注冊webContent
的new-window
事件處理程序。
window.opener.postMessage(message, targetOrigin)
message
StringtargetOrigin
String
將消息發送給指定來源的父窗口,如果未指定來源則發送給*
,即所有窗口。
使用 Chrome 的 window.open()
如果要使用 Chrome 的內置 window.open()
,請在 webPreferences
選項中將 nativeWindowOpen
設置為 true
。
原生 window.open ()
允許同步打開窗口, 因此可以方便的選擇是對話框還是首選項窗口。
該選項也可以設置在<webview>
標簽上:
<webview webpreferences="nativeWindowOpen=yes"></webview>
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('<h1>Hello</h1>')
例: 打開一個子窗口並向父窗口傳遞消息
主線程腳本
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
<!DOCTYPE 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>
效果
例:在父窗口中控制關閉子窗口
在第一個例子中演示打開窗口並回傳信息,那如果要在主窗口中關閉子窗口怎么做呢?這時候就要用
BowserWindowProxy對象了
Returns
BrowserWindowProxy
- 創建一個新窗口,並返回一個BrowserWindowProxy
類的實例。
這個對象是創建新窗口返回的
api參考:
https://www.electronjs.org/docs/api/browser-window-proxy
將上面的主窗口代碼稍微改下
<!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>
<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>
關於window open函數的疑問
在第二例子中,我發現不管我點擊幾次彈出子窗口,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())
}