Reputation: 31
I'm new to Electron, and I'm trying to do a function from a click on a menu. Here is my example.
index.html
<!DOCTYPE html>
<html lang="pt-br" dir="ltr">
<head>
<meta charset="utf-8">
<title>Electron</title>
<script src="main.js"></script>
</head>
<body>
<input type="text" name="campo" id="campo" value="">
<button type="button" name="funcao" onclick="funcao()">Função</button> <br /><br />
<input type="text" name="url" id="url">
</body>
</html>
In this example, typing something into the "url" input and clicking the button will show what was typed in the "campo" input. What I wanted to do is do the same but by clicking on the "funcao" menu.
main.js
(part of the menu with the function below)
{
label: 'Função',
click () { funcao(); }
},
function funcao() {
document.getElementById("campo").value = document.getElementById("url").value;
}
The error is this:
"ReferenceError: document is not defined"
Edit: My english is bad, I used Google Translate, sorry.
Upvotes: 1
Views: 6032
Reputation: 417
Electron has two processes, the main
and the render
process. The main process is basically where all the heavy lifting and the app setup itself happens. The render process on the other hand is where all the HTML rendering happens. Usually you have one main process and every BrowserWindow, WebView, ... has it's own render process.
And here is the catch, the main process is not aware of the DOM that is rendered. However, you can communicate between the main and render processes via IPC messages.
For more details, I highly recommend the documentation about application architecture https://electronjs.org/docs/tutorial/application-architecture
Option A:
In your case, as you are creating the menu from the main process, you don't have access to the render processes DOM. What you need to do in your click handler is to send an IPC message to your BrowserWindow. There you listen to the call and trigger funcao();
Remodelled example from the docs:
// In main process.
const {ipcMain} = require('electron')
const mainWindow = ... // reference to the BrowserWindow
mainWindow.webContents.send('asynchronous-message', 'ping')
// In renderer process (web page).
const {ipcRenderer} = require('electron')
ipcRenderer.on('asynchronous-message', (event, arg) => {
console.log(arg) // prints "ping"
})
Option B:
Just create your menu inside the render process and you have access to the window object and all the other browser APIs.
From my point of view, there is no "best" way about where to put the code for the menu creation as main and render process has both up- and downsides.
Upvotes: 3