/* 大家好,我是第一次接触Electron。我以前用过JavaScript。有人可以告诉我我在尝试让按钮 onclick 事件调用一个带有 console.log 操作的简单函数时做错了什么吗?任何帮助将不胜感激,因为我不确定所有部分放在哪里。
这是我的代码: */
// main.js
const { app, BrowserWindow, ipcMain } = require("electron");
let win = null;
const createWindow = () => {
win = new BrowserWindow({
width: 800,
height: 600,
resizable: false,
webPreferences: {
nodeIntegration: true
}
});
win.loadFile("index.html");
};
app.whenReady().then(createWindow);
ipcMain.on("callMyFunction", (event, data) => {
// Prints inside the label called funcCallTxt
funcCallTxt.innerHTML = "This event: " + event + " and This data: " + data;
// Writes to the console just to see what in the variables
console.log("This event: " + event + " and This data: " + data)
});
// renderer.js
const { contextBridge, ipcRenderer } = require("electron");
contextBridge.exposeInMainWorld("electron", {
send: (channel, payload) => ipcRenderer.send(channel, payload),
});
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script defer src="renderer.js"></script>
<title>Call a Function</title>
</head>
<body>
<h1>A Function Call</h1>
<label for="funcCallTxt"></label>
<button type="button" onclick="callMyFunction()">Call My Function</button>
</body>
</html>
我忘记说了。这段代码绝对没有任何输出。什么也没发生,控制台也没有打印任何内容。
有几点需要指出:
funcCallTxt.innerHTML
不起作用。 这需要在渲染器中完成。contextBridge.exposeInMainWorld
是您需要在预加载文件中使用的方法,而不是渲染器。 您在此预加载文件中定义的方法将通过您在预加载中定义的全局变量在渲染器中可用。 在您的示例中,这是全局变量是 electron
。ipcMain事件的
event.returnValue
方法。将所有内容放在一起,这里是一个基于您的示例的基本示例,说明其如何工作:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script defer src="renderer.js"></script>
<title>Call a Function</title>
</head>
<body>
<h1>A Function Call</h1>
<label for="funcCallTxt"></label>
<button type="button" onclick="callMyFunction()">Call My Function</button>
</body>
</html>
main.js
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('node:path')
let win
function createWindow() {
win = new BrowserWindow({
width: 800,
height: 600,
resizable: false,
webPreferences: {
nodeIntegration: true,
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
win.webContents.on('did-finish-load', () => {
win.show()
})
}
app.whenReady().then(createWindow)
// Listen for funcCallTxt call from preload.
// Then return a value and console.log when called.
ipcMain.on('funcCallTxt', (event, data) => {
// "data" is what you passed to electron.send function in renderer
// Value to be sent back to renderer thru preload:
event.returnValue = data + ' = 2'
// "event" here is the Electron.IpcMainEvent object
console.log('This event: ' + event + ' and This data: ' + data)
})
预加载.js
const { contextBridge, ipcRenderer } = require('electron')
// Expose following to renderer under 'electron' global
contextBridge.exposeInMainWorld('electron', {
// Send funcCallTxt directive to main with the data parameter from renderer
send: (data) => ipcRenderer.sendSync('funcCallTxt', data)
})
渲染器.js
function callMyFunction() {
// Send the string "1 + 1" to main thru send function defined in preload and
// assign the return value from main to the variable "fromMain"
const str = '1 + 1'
const fromMain = electron.send(str)
document.querySelector('[for="funcCallTxt"]').innerHTML = fromMain
}