【问题标题】:How to access DOM elements in electron?如何访问电子中的 DOM 元素?
【发布时间】:2015-12-23 04:48:30
【问题描述】:

我正在尝试向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 对象吗?还是有任何其他替代方式可以为我提供所需的功能?

【问题讨论】:

  • 主进程无权访问 DOM,只有渲染器才能访问。 Learn the difference
  • 你能把你的 index.html 贴在这里

标签: javascript dom electron


【解决方案1】:

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

main processrenderer process 上提供了一个 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);
});

【讨论】:

  • 当我在 index.html 中使用 require 时,会出现以下错误。` Uncaught ReferenceError: require is not defined 知道为什么吗?
  • 您似乎忘记包含错误。我目前无法访问电子,但我认为require() 应该在渲染器进程中可用。编辑:好的,现在就在这里。
  • @ant_1618 你用的是什么版本的 Electron?另外,在什么操作系统上?
  • 在 Linux 15.04 上使用 io.js v2.3.1 和 Electron 0.29.1
  • @ROAL:是的,确实可以使用.once()。 Electron 的 IPC 是标准的 Node.js EventEmitter。此外,require('ipc') 已贬值,现在是require('electron').ipcMainrequire('electron').ipcRenderer
【解决方案2】:

您可以使用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);
});

【讨论】:

  • 这样做时最好不要允许任何类型的用户输入或外部数据。
【解决方案3】:

this tutorial中所述:

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

因此您可以按照https://github.com/electron/electron-api-demos 中的示例进行操作。每个html 都应该有一个js 文件。在那个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>

【讨论】:

    【解决方案4】:

    在我的例子中,窗口是通过调用 window.open 创建的 默认情况下,电子 NodeIntegration 被禁用,因此您无法访问其他窗口的 DOM。 将属性 nativeWindowOpen 更改为 true 解决了我的问题。

    // in main.ts
    async function createWindow() {
      const win = new BrowserWindow({
        // ....
        webPreferences: {
          nativeWindowOpen: true,
        }
      })
    

    现在我可以在使用 window.open 创建窗口时访问 window.document 元素

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多