首页 文章

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

提问于
浏览
48

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

3 回答

  • 61

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

    DOM无法在主进程中访问,只能在它所属的渲染器中访问 .

    main process上有一个 ipc 模块以及renderer process,允许通过同步/异步消息在这两个模块之间进行通信 .

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

    如_1785070中所述:

    在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>
    

相关问题