Electron window.open 函數 和 Browser-window-proxy 對象的使用


官方文檔:

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 String
  • frameName 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 參數中的任何已注冊 webContentnew-window 事件處理程序。

window.opener.postMessage(message, targetOrigin)

  • message String
  • targetOrigin String

將消息發送給指定來源的父窗口,如果未指定來源則發送給*,即所有窗口。

使用 Chrome 的 window.open()

如果要使用 Chrome 的內置 window.open(),請在 webPreferences 選項中將 nativeWindowOpen 設置為 true

原生 window.open () 允許同步打開窗口, 因此可以方便的選擇是對話框還是首選項窗口。

該選項也可以設置在<webview>標簽上:

<webview webpreferences="nativeWindowOpen=yes"></webview>

BrowserWindow的創建可通過WebContentsnew-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>

效果

image-20210202163535398

例:在父窗口中控制關閉子窗口

在第一個例子中演示打開窗口並回傳信息,那如果要在主窗口中關閉子窗口怎么做呢?這時候就要用

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>

image-20210202172415879

關於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())
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM