• 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({
       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,
           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({
             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{
                 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{
                 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())
    }
    
  • 相关阅读:
    C#Task和async/await使用
    jQuery实现C#CheckBoxList模糊搜索
    [转载].NET ASP.NET 中web窗体(.aspx)利用ajax实现局部刷新
    MD5加密方法HashPasswordForStoringInConfigFile(string,string)过时问题处理方法
    .NET WebFrom跨时区项目时间问题处理方法
    C# 中的Async 和 Await 的用法详解
    cron表达式
    ASP.NET MVC实现单用户登录
    一个简单便捷的树形显示Ztree
    身份证代码
  • 原文地址:https://www.cnblogs.com/makalochen/p/14363333.html
Copyright © 2020-2023  润新知