How to access DOM elements in electron?

柔情痞子 提交于 2019-12-17 04:54:25

问题


I am trying to add functionality to a button in index.html file is as follows: I have a button element in index.html

<button id="auth-button">Authorize</button>

In main.js of the app, I have

require('crash-reporter').start();
console.log("oh yaeh!");
var mainWindow = null;

app.on('window-all-closed', function(){
    if(process.platform != 'darwin'){
        app.quit();
    }
});

app.on('ready',function(){
    mainWindow = new BrowserWindow({width:800, height : 600});
    mainWindow.loadUrl('file://' + __dirname + '/index.html');

    var authButton = document.getElementById("auth-button");
    authButton.addEventListener("click",function(){alert("clicked!");});

    mainWindow.openDevTools();

    mainWindow.on('closed',function(){
        mainWindow = null;
    });
});

But an error occurs as follows: Uncaught Exception: ReferenceError: document is not defined

Can the DOM objects be accessed while building electron apps? or is there any other alternative way that can give me the required functionality?


回答1:


DOM can not be accessed in the main process, only in the renderer that it belongs to.

There is an ipc module, available on main process as well as the renderer process that allows the communication between these two via sync/async messages.

You also can use the remote module to call main process API from the renderer, but there's nothing that would allow you to do it the other way around.

If you need to run something in the main process as a response to user action, use the ipc module to invoke the function, then you can return a result to the renderer, also using ipc.

Code updated to reflect actual (v0.37.8) API, as @Wolfgang suggested in comment, see edit history for deprecated API, if you are stuck with older version of Electron.

Example script in index.html:

var ipc = require('electron').ipcRenderer;
var authButton = document.getElementById('auth-button');
authButton.addEventListener('click', function(){
    ipc.once('actionReply', function(event, response){
        processResponse(response);
    })
    ipc.send('invokeAction', 'someData');
});

And in the main process:

var ipc = require('electron').ipcMain;

ipc.on('invokeAction', function(event, data){
    var result = processData(data);
    event.sender.send('actionReply', result);
});



回答2:


You can use webContents.executeJavaScript(code[, userGesture, callback]) API to execute JavaScript code.

for example:

mainWindow.loadUrl('file://' + __dirname + '/index.html');
mainWindow.webContents.on('did-finish-load', ()=>{
    let code = `var authButton = document.getElementById("auth-button");
            authButton.addEventListener("click",function(){alert("clicked!");});`;
    mainWindow.webContents.executeJavaScript(code);
});



回答3:


As stated in this tutorial:

In Electron, we have several ways to communicate between the main process and renderer processes, such as ipcRenderer and ipcMain modules for sending messages, and the remote module for RPC style communication.

So you can follow the example in https://github.com/electron/electron-api-demos. You should have a js file for each html. In that js file, you can use require anytime you want.

Code in renderer.js:

const ipc = require('electron').ipcRenderer

const asyncMsgBtn = document.getElementById('async-msg')

asyncMsgBtn.addEventListener('click', function () {
  ipc.send('asynchronous-message', 'ping')
})

ipc.on('asynchronous-reply', function (event, arg) {
  const message = `Asynchronous message reply: ${arg}`
  document.getElementById('async-reply').innerHTML = message
})

Code in ipc.html:

<script type="text/javascript">
  require('./renderer-process/communication/sync-msg')
  require('./renderer-process/communication/async-msg')
  require('./renderer-process/communication/invisible-msg')
</script>


来源:https://stackoverflow.com/questions/32780726/how-to-access-dom-elements-in-electron

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!