web-dev-qa-db-fra.com

Comment accéder aux éléments DOM en électron?

J'essaie d'ajouter des fonctionnalités à un bouton dans index.html Le fichier est comme suit: J'ai un élément de bouton dans index.html

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

Dans main.js de l'application, j'ai

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

Mais une erreur se produit comme suit: Uncaught Exception: ReferenceError: document is not defined

Peut-on accéder aux objets DOM lors de la création d'applications électroniques? ou y a-t-il une autre manière alternative qui peut me donner la fonctionnalité requise?

55
ant_1618

DOM n'est pas accessible dans le processus principal, mais uniquement dans le rendu auquel il appartient.

Il existe un module ipc disponible sur le processus principal ainsi que sur le processus de rend qui permet la communication entre ces deux via des messages sync/async.

Vous pouvez également utiliser le module remote pour appeler l'API du processus principal à partir du rendu, mais rien ne vous permet de le faire à l'inverse.

Si vous devez exécuter quelque chose dans le processus principal en réponse à une action de l'utilisateur, utilisez le module ipc pour appeler la fonction. Vous pouvez alors renvoyer un résultat au rendu, également à l'aide de ipc.

Code mis à jour pour refléter l'API actuelle (v0.37.8), comme @Wolfgang l'a suggéré dans le commentaire, voir l'historique de modification pour l'API obsolète, si vous êtes coincé avec une version antérieure d'Electron

Exemple de script dans 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');
});

Et dans le processus principal:

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

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

Vous pouvez utiliser webContents.executeJavaScript (code [ userGesture, callback]) API pour exécuter du code JavaScript.

par exemple:

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

Comme indiqué dans ce tutoriel :

Dans Electron, nous disposons de plusieurs moyens pour communiquer entre le processus principal et les processus de rendu, tels que les modules ipcRenderer et ipcMain pour l'envoi de messages et le module distant pour la communication de style RPC.

Vous pouvez donc suivre l'exemple dans https://github.com/electron/electron-api-demos . Vous devriez avoir un fichier js pour chaque html. Dans ce fichier js, vous pouvez utiliser require à tout moment.

Code en 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
})

Code en 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>
6
onmyway133