如何在Electron中访问DOM元素?

问题描述 投票:0回答:4

我正在尝试向

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 对象吗?或者有其他替代方法可以为我提供所需的功能吗?

javascript dom electron
4个回答
96
投票

DOM 不能在主进程中访问,只能在它所属的渲染器中访问。 有一个

ipc

模块,可在

主进程
以及渲染器进程上使用,允许这两个进程通过同步/异步消息进行通信。 您还可以使用

remote

模块从渲染器调用主进程 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); });



31
投票
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); });



10
投票
本教程

中所述:

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

因此您可以按照
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>



1
投票
window.open

创建的 默认情况下,Electron NodeIntegration 被禁用,因此您无法访问其他窗口的 DOM。 将属性

nativeWindowOpen
更改为 true 解决了我的问题。
// in main.ts
async function createWindow() {
  const win = new BrowserWindow({
    // ....
    webPreferences: {
      nativeWindowOpen: true,
    }
  })

现在,当我使用 
window.open

 创建窗口时,我可以访问 window.document 元素

更新:删除了 Electron>=v18.0

的属性选项 https://www.electronjs.org/docs/latest/writing-changes#planned-writing-api-changes-180
nativeWindowOpen: true

现在这是默认设置,您无法更改它(感谢编辑@kai_onthereal)

© www.soinside.com 2019 - 2024. All rights reserved.