如何访问电子中的DOM元素?


74

我正在尝试向index.html文件中的按钮添加功能,如下所示:我在按钮元素中index.html

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

main.js应用程序中,我有

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;
    });
});

但是会发生如下错误: Uncaught Exception: ReferenceError: document is not defined

构建电子应用程序时可以访问DOM对象吗?还是有其他替代方法可以为我提供所需的功能?


2
主进程无权访问DOM,而是渲染器具有访问权。了解差异
Ben Fortune

您可以在此处粘贴index.html
DDphp

Answers:


84

不能在主进程中访问DOM ,只能在其所属的渲染器中访问。

ipc主进程以及渲染器进程上都有一个模块,该模块允许通过同步/异步消息在这两者之间进行通信。

您还可以使用远程模块从渲染器调用主流程API,但是没有其他方法可以使您执行此操作。

如果您需要在主流程中运行某些内容作为对用户操作的响应,请使用ipc模块调用该函数,然后也可以使用将结果返回到渲染器ipc

已更新代码以反映实际(v0.37.8)API,如@Wolfgang在注释中建议的那样,如果您对旧版本的Electron感到困惑,请参阅不推荐使用的API的编辑历史记录。

中的示例脚本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');
});

并在主要过程中:

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

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

1
当我在index.html中使用require时,出现以下错误。`Uncaught ReferenceError: require is not defined知道为什么吗?
ant_1618 2015年

看来您忘记了包含错误。我目前无法使用电子,但我认为require()渲染器过程中应该可以使用电子。编辑:好的,现在在这里。
ROAL 2015年

@ ant_1618您正在使用什么版本的Electron?另外,在什么操作系统上?
ROAL 2015年

在Linux 15.04上使用io.js v2.3.1和Electron 0.29.1
ant_1618 2015年

2
@ROAL:是的,确实可以使用.once()。Electron的IPC是标准的Node.js EventEmitter。而且,require('ipc')已经折旧了,现在require('electron').ipcMainrequire('electron').ipcRenderer
沃尔夫冈

23

您可以使用webContents.executeJavaScript(code [,userGesture,callback]) API执行JavaScript代码。

例如:

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);
});

2
最好不要在执行此操作时允许任何类型的用户输入或外部数据。
库珀

9

本教程所述

在Electron中,我们有几种在主进程和渲染器进程之间进行通信的方式,例如用于发送消息的ipcRenderer和ipcMain模块,以及用于RPC样式通信的远程模块。

因此,您可以按照https://github.com/electron/electron-api-demos中的示例进行操作。js每个文件都应有一个文件html。在该js文件中,您可以require随时使用。

代码在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
})

代码在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>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.