我对 electro.js 完全陌生,我只是想在同一个浏览器窗口(已经加载了 index1.html)中单击按钮加载一个新页面(称之为 index2.html)。我试图实现这一点,当单击按钮时,与 BrowserWindow 相对应的渲染进程向主进程发送一个 ipc 事件,然后主进程通过调用 loadFile() 将新的 html 加载到 BrowserWindow 中。我在这里面临的问题是单击按钮后,新页面无法加载。我已经验证主进程使用控制台打印捕获了 ipc 事件。此外,窗口上的其他操作(例如窗口最小化)也正在运行。 有人可以帮我理解我哪里出了问题吗?
package.json
{
"name": "hello-world",
"version": "1.0.0",
"main": "main.js",
"devDependencies": {
"electron": "^9.2.0"
},
"scripts":{
"start":"electron ."
}
}
main.js
console.log("Main process running");
const electron = require("electron");
const app = electron.app ;
const BrowserWindow = electron.BrowserWindow;
const path = require("path");
const url = require("url");
const ipc = electron.ipcMain
let win;
function createWindow()
{
win = new BrowserWindow({
webPreferences: {nodeIntegration: true},
show:false
});
win.loadFile('src/html/index.html');
win.on('ready-to-show',()=>{
win.show();
})
;
}
ipc.on('login-success',function(event,arg){
console.log("Hello World");//Making sure that main process catches the event
//load new url
win.loadFile('src/html/index2.html');//does nothing
/*
the following command works though
win.minimize();
*/
});
app.on('ready',createWindow);
index.html
<html>
<head>
<link rel="stylesheet" href="../css/index.css">
<link href="https://fonts.googleapis.com/css?family=Ubuntu" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>ChatIn</title>
</head>
<body>
<div class="main">
<p class="sign" align="center">Sign in</p>
<form class="form1">
<input class="un " type="text" align="center" placeholder="Username">
<input class="pass" type="password" align="center" placeholder="Password">
<button class="submit" align="center">Sign in</button>
<p class="forgot" align="center"><a href="#">Forgot Password?</p>
<script>
require("../js/login.js")
</script>
</div>
</body>
</html>
login.js
const electron = require("electron");
const ipc = electron.ipcRenderer;
const btnArray = document.getElementsByClassName("submit");
const loginBtn = btnArray[0];
loginBtn.addEventListener('click',(event)=>{
ipc.send('login-success');
},false);
index2.html(我认为这不会影响手头的问题,但它仍然在这里)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Welcome</title>
<link rel="stylesheet" href="../css/index2.css">
</head>
<body>
<section class="msger">
<header class="msger-header">
<div class="msger-header-title">
<i class="fas fa-comment-alt"></i> SimpleChat
</div>
<div class="msger-header-options">
<span><i class="fas fa-cog"></i></span>
</div>
</header>
<main class="msger-chat">
<div class="msg left-msg">
<div
class="msg-img"
style="background-image: url(https://image.flaticon.com/icons/svg/327/327779.svg)"
></div>
<div class="msg-bubble">
<div class="msg-info">
<div class="msg-info-name">BOT</div>
<div class="msg-info-time">12:45</div>
</div>
<div class="msg-text">
Hi, welcome to SimpleChat! Go ahead and send me a message. 😄
</div>
</div>
</div>
<div class="msg right-msg">
<div
class="msg-img"
style="background-image: url(https://image.flaticon.com/icons/svg/145/145867.svg)"
></div>
<div class="msg-bubble">
<div class="msg-info">
<div class="msg-info-name">Sajad</div>
<div class="msg-info-time">12:46</div>
</div>
<div class="msg-text">
You can change your name in JS section!
</div>
</div>
</div>
</main>
<form class="msger-inputarea">
<input type="text" class="msger-input" placeholder="Enter your message...">
<button type="submit" class="msger-send-btn">Send</button>
</form>
</section>
</body>
</html>
我尝试/注意到的事情
win=null
不会关闭浏览器窗口,但是
win.close()
或 win.destroy()
工作,不知道为什么。 使用 var 而不是 let 作为 win 变量
const { pathToFileURL } = require('url');
//...
win.loadUrl(pathToFileURL(path.resolve(__dirname, './html2.html')).href);
onClick="parent.location='index2.html'"
这会将浏览器窗口页面从inex1.html更改为index2.html,反之亦然:D
例如,在我正在开发的应用程序中,我需要登录(在主窗口中加载),如果成功,则重定向到另一个页面(使用相同的浏览器窗口)。为此,我需要首先将渲染器进程的登录成功的反馈发送给主进程,然后主进程将负责加载新内容。
这就是我的渲染器进程通过 IPC 向主进程发送消息的方式
//#region Modules
var $ = require('jquery');
const {ipcRenderer, ipcMain} = require('electron') //You must require the ipcRenderer
//#endregion
let btnLogin = $("#btnLogin")
btnLogin.on('click', e => {
let txtLogin = $("#txtLogin").val(),
txtSenha = $("#txtSenha").val()
if (txtLogin == "")
{
Swal.fire({
icon: 'error',
title: 'Oops...',
text: 'Você precisa informar o login',
})
}
if (txtSenha == "")
{
Swal.fire({
icon: 'error',
title: 'Oops...',
text: 'Você precisa informar a senha',
})
}
if (txtLogin != "" && txtSenha != "")
{
var usuario =
{
"email": txtLogin,
"senha": txtSenha
}
$.ajax({
//Simple ajax here
complete: function (xhr, textStatus, jsonResult) {
if (xhr.status == 400)
{
Swal.fire({
icon: 'error',
title: 'Oops...',
text: 'Aconteceu algo de errado, tente novamente',
})
}
if (xhr.status == 200)
{
//Salvar na sessão
Swal.fire({
icon: 'success',
title: 'Yes, yes, yes!',
text: 'Login efetuado com sucesso',
})
ipcRenderer.send('login-success') /*<- this is how the
renderer process
send the message, using its IPC to send a message to the channel
'login-success' (you can name it as you like and also send whatever you need
}
}
});
}
})
这就是我的 main.js 监听渲染器进程发送的消息的方式
const {app, BrowserWindow, ipcMain} = require('electron') //You must require de ipcMain
const windowStateKeeper = require('electron-window-state')
let
mainWindow
function createWindow () {
let state = windowStateKeeper({
defaultWidth: 500,
defaultHeight: 650
})
mainWindow = new BrowserWindow({
x: state.x, y: state.y,
width: state.width, height: state.height,
minWidth: 378, minHeight: 700,
webPreferences: {
contextIsolation: false,
nodeIntegration: true
},
icon: './icons8-headset-98.ico'
})
mainWindow.loadFile('renderer/login.html')
mainWindow.webContents.openDevTools();
mainWindow.on('closed', () => {
mainWindow = null
})
state.manage(mainWindow)
}
app.on('ready', createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
app.on('activate', () => {
if (mainWindow === null) createWindow()
})
ipcMain.on('login-success', e => { /*Here, the main process is listening in the same channel
that the renderer process send the message, it needs to recieve the event callback too*/
console.log('Entrou no main');
mainWindow.loadFile('renderer/chamados.html') /*And lastly, you just have to load the new
content in the window that you created previously*/
})