Подтвердить что ты не робот

Как получить доступ к элементам DOM в электронном?

Я пытаюсь добавить функциональность к кнопке в файле 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 при создании электронных приложений? или есть ли другой альтернативный способ, который может дать мне необходимую функциональность?

4b9b3361

Ответ 1

DOM не может быть доступен в основном процессе, только в рендерере, к которому он принадлежит.

Существует модуль ipc, доступный в основном процессе, а также процесс визуализации, который позволяет осуществлять связь между этими двумя через сообщения sync/async.

Вы также можете использовать модуль remote для вызова основного API процесса из средства визуализации, но нет ничего, что позволило бы вам сделать это наоборот.

Если вам нужно запустить что-то в основном процессе в ответ на действие пользователя, используйте модуль ipc для вызова функции, затем вы можете вернуть результат рендереру, также используя ipc.

Код обновлен, чтобы отразить фактический (v0.37.8) API, как @Wolfgang, предложенный в комментарии, см. историю изменений для устаревших API, если вы застряли в более старой версии Electron.

Пример script в 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);
});

Ответ 2

Вы можете использовать webContents.executeJavaScript(код [, 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

Как указано в этом https://github.com/electron/electron/blob/master/docs/tutorial/quick-start.md

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

Итак, вы можете следовать примеру в https://github.com/electron/electron-api-demos. У вас должен быть файл js для каждого html, там вы можете использовать require в любое время

Код в renderer.js https://github.com/electron/electron-api-demos/blob/master/renderer-process/communication/async-msg.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
})

Код в html https://github.com/electron/electron-api-demos/blob/master/sections/communication/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>