【问题标题】:how to open new window in place of current window in Electron如何在电子中打开新窗口代替当前窗口
【发布时间】:2019-05-28 04:25:04
【问题描述】:

当我单击一个按钮时,我已经能够打开一个新窗口,但是,它是一个新的弹出窗口。如何在主窗口的位置打开新窗口?

var app = require('app')
var BrowserWindow = require('browser-window')
var ipc = require('ipc')

app.on('ready', function () {
    var mainWindow = new BrowserWindow ({
        width: 800,
        height: 600
    })
    mainWindow.loadURL('file://' + __dirname + '/main.html')
    //mainWindow.openDevTools() //opens inspect console

    var prefsWindow = new BrowserWindow ({
        width: 400,
        height: 400,
        show: false
    })
    prefsWindow.loadURL('file://' + __dirname + '/prefs.html')

使用上面的代码,会弹出一个新窗口。我附上了一张截图来说明我的意思。

popup window

我希望用“首选项”替换主窗口(以及添加后替换主窗口的其他选项),而不是那个弹出窗口。

【问题讨论】:

  • 是关注windows的定位吗?即您是否试图让 prefsWindow 与 mainWindow 位于完全相同的位置或不同的位置?

标签: javascript electron


【解决方案1】:

无需创建新窗口,只需将 prefs.html 加载到主窗口中即可。您的旧内容 (main.html) 将被替换,而无需打开额外的窗口。

当相应的按钮放置在 main.html 中时,您需要通过 ipc 远程模块应用此加载。

对于 Electron 0.35.0 及更高版本,请遵循 this SO answer

// In main process.
const ipcMain = require('electron').ipcMain;

// in main process, outside of app.on:
ipc.on('load-page', (event, arg) => {
    mainWindow.loadURL(arg);
});

// In renderer process (web page).
const ipc = require('electron').ipcRenderer;

然后可以按如下方式加载新页面:

ipc.send('load-page', 'file://' + __dirname + '/prefs.html');

【讨论】:

    【解决方案2】:

    如果有人感兴趣,这就是我所做的。

    假设我有 login form 并且在登录后我想显示将要发生的事情的主窗口。

    设置您的index.js

    const electron = require('electron');
    const url = require('url');
    const path = require('path');
    
    const { app, BrowserWindow } = electron;
    
    let loginWindow;
    var mainIndex = '../../index.html'; //the login window
    var directoryHtml = '../html/'; //directory of where my html file is, the main window is here except the login window
    var iconPath = '../../images/logo.png'; //replace with your own logo
    let { ipcMain } = electron;
    var newWindow = null;
    
    app.on('ready', function () {
        loginWindow = new BrowserWindow({//1. create new Window
            height: 600, width: 450,
            minHeight: 600, minWidth: 450, //set the minimum height and width
            icon: __dirname + iconPath,
            frame: false, //I had my own style of title bar, so I don't want to show the default
            backgroundColor: '#68b7ad', //I had to set back color to window in case the white screen show up
            show: false //to prevent the white screen when loading the window, lets not show it first
        });
    
        loginWindow.loadURL(url.format({ //2. Load HTML into Window
            pathname: path.join(__dirname, mainIndex),
            protocol: 'file',
            slashes: true
        }));
    
        loginWindow.once('ready-to-show', () => {
            loginWindow.show() //to prevent the white screen when loading the window, lets show it when it is ready
        })
    });
    
    //dynamically resize window when this function is called
    ipcMain.on('resize', function (e, x, y) {
        loginWindow.setSize(x, y);
    }); 
    
    /** start of showing new window and close the login window **/
    ipcMain.on('newWindow', function (e, filenName) {
    
        if(newWindow){
            newWindow.focus(); //focus to new window
            return;
        }
    
        newWindow = new BrowserWindow({//1. create new Window
            height: 600, width: 800,
            minHeight: 600, minWidth: 800,
            icon: __dirname + iconPath,
            frame: false,
            backgroundColor: '#68b7ad',
            show: false
        }); 
    
        newWindow.loadURL(url.format({ //2. Load HTML into new Window
            pathname: path.join(__dirname, directoryHtml + filenName),
            protocol: 'file',
            slashes: true
        }));
    
        newWindow.once('ready-to-show', () => { //when the new window is ready, show it up
            newWindow.show()
        })
    
        newWindow.on('closed', function() { //set new window to null when we're done
            newWindow = null
        })
    
        loginWindow.close(); //close the login window(the first window)
    });
    /** end of showing new window and closing the old one **/
    
    app.on('closed', function () {
        loginWindow = null;
    });
    
    // Quit when all windows are closed.
    app.on('window-all-closed', function () {
        // On OS X it is common for applications and their menu bar
        // to stay active until the user quits explicitly with Cmd + Q
        if (process.platform !== 'darwin') {
            app.quit()
        }
    })
    
    app.on('activate', function () {
        // On OS X it's common to re-create a window in the app when the
        // dock icon is clicked and there are no other windows open.
        if (loginWindow === null) {
            createWindow()
        }
    })
    

    index.html

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Login Window</title>
    </head>
    
    <body>
        <h1>Login</h1>
        <!-- . . . . -->
        <button id="btn-login" onclick="loginNow()"></button>
        <!-- . . . . -->
        <script>
            function loginNow(){
                //.....
                //assuming the authentication is valid, we want to show now the new window which will be our main window
                const { ipcRenderer } = require('electron'); //require electron
    
                //using ipcRenderer, let's call the function in index.js where the function name is `newWindow`, 
                //the `main.html` is the new html file I want to show, use your own.
                ipcRenderer.send('newWindow','main.html'); 
            }
        </script>
    </body>
    
    </html>
    

    如果这是正确的方法,我不知道,我不知道这样做的缺点,但我希望没有。希望这对某人有所帮助。

    【讨论】:

    • 谢谢,我不确定这是不是最好的方法。但我使用了你的方法,它对我有很大帮助,如果有最新最好的方法,请告诉我。
    【解决方案3】:

    你有几个选择。

    您可以致电prefsWindow.focus() 以确保第二个窗口位于第一个窗口之上。

    您可以使用mainWindow.hide()mainWindow.destroy() 隐藏或关闭主窗口,只留下第二个窗口打开。完成后重新打开它。

    或者,您可以将首选项页面加载到第一个窗口中,然后再返回主页面,而不是有两个窗口。

    【讨论】:

    • 否,点击首选项。我希望在主窗口中加载 prefs.html 页面而不是新页面。
    【解决方案4】:

    在创建一个在访问实际内容之前首先需要身份验证的应用程序时,我遇到了类似的问题。所以应用程序的第一页和主页面是一个登录表单。登录成功后,应该在实际内容所在的位置加载一个新页面。为此,我做了以下工作:

    在 main.js 或 index.js 中,您将如何命名它,而不是在开始时加载第二个窗口然后显示它,而是在 IPC 事件侦听器中加载它。因此,当 IPC 侦听器收到某个事件时,它会加载页面。

    const {ipcMain} = require('electron');
    
    ipcMain.on('login', (event, arg) => {
    loginPage.loadURL(url.format({
    pathname: path.join(__dirname, 'mainpage.html'),
    protocol: 'file',
    slashes: true
    }));
    });
    

    注意,loginPage 是我在 app.on() 上创建的主窗口,而 mainpage 是成功登录后创建的第二个页面。

    然后在我的 loginPage.html 中,在我验证登录后,如果成功,我会将该 IPC 渲染器消息发送回主进程。这很简单:

    var ipc = require('electron').ipcRenderer;
    
    ipc.send('login', 'an-argument');
    

    上述方法应该有效。我只是一个初学者,所以我不能说这是否是最好的方法,或者它是否有任何没有立即看到的不需要的含义,但它对我来说已经解决了,所以你不妨试一试。

    【讨论】:

      【解决方案5】:

      在找到一个简单的解决方案之前,我一直在解决与您相同的问题。 这是JS代码:

      const electron = require('electron');
      let rootPath = "src/Page/index.html" //Path to the html file
      
      LoadNewWindowInCurrent(rootPath); //Opens new html file in current window
      
      //Here's the ready function for you to use
      function LoadNewWindowInCurrent (PathToHtml){
         let localWindow = electron.remote.getCurrentWindow(); 
         localWindow.LoadFile(PathToHtml);
      }
      

      【讨论】:

        猜你喜欢
        • 2021-02-20
        • 2014-08-29
        • 1970-01-01
        • 1970-01-01
        • 2017-07-13
        • 2014-03-24
        • 2019-10-07
        • 2022-07-02
        • 1970-01-01
        相关资源
        最近更新 更多