2015-09-25 22 views
37

Sto cercando di aggiungere funzionalità a un pulsante in index.html file è il seguente: Ho un elemento pulsante nella index.htmlCome accedere agli elementi DOM nell'elettrone?

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

In main.js della app, ho

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

Ma un l'errore si verifica come segue: Uncaught Exception: ReferenceError: document is not defined

È possibile accedere agli oggetti DOM durante la creazione di app elettroniche? o c'è qualche altro modo alternativo che può darmi la funzionalità richiesta?

+2

Il processo principale non lo fa avere accesso al DOM, è il renderer che ha accesso. [Impara la differenza] (https://github.com/atom/electron/blob/master/docs/tutorial/quick-start.md#differences-between-main-process-and-renderer-process) –

+0

Puoi incollare il tuo index.html qui –

risposta

51

DOM può non accessibile nel processo principale, solo nel renderer a cui appartiene.

C'è un modulo ipc, disponibile su main process e renderer process che consente la comunicazione tra questi due tramite messaggi di sincronizzazione/asincroni.

È inoltre possibile utilizzare il modulo remote per richiamare l'API di processo principale dal renderer, ma non c'è nulla che possa consentire di eseguire l'operazione inversa.

Se è necessario eseguire qualcosa nel processo principale come risposta all'azione dell'utente, utilizzare il modulo ipc per richiamare la funzione, quindi è possibile restituire un risultato al renderer, utilizzando anche ipc.

Codice aggiornato per riflettere l'API effettiva (v0.37.8), come suggerito da @Wolfgang nel commento, consultare la cronologia delle modifiche per API deprecate, se si è bloccati con la versione precedente di Electron.

Esempio di script in 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'); 
}); 

E nel processo principale:

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

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

Quando uso require in index.html viene visualizzato il seguente errore. 'Uncaught ReferenceError: require is not defined 'nessuna idea perché? –

+0

Sembra che tu abbia dimenticato di includere l'errore. Al momento non ho accesso a electron, ma penso che 'require()' dovrebbe essere disponibile nel processo di rendering. Modifica: OK ora è qui. – ROAL

+0

@ ant_1618 Quale versione di Electron stai usando? Inoltre, su quale sistema operativo? – ROAL

10

È possibile utilizzare webContents.executeJavaScript(code[, userGesture, callback]) API per eseguire codice JavaScript.

ad esempio:

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

come indicato dal presente 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. 

Così si può seguire l'esempio in https://github.com/electron/electron-api-demos.Si dovrebbe avere un file per ogni jshtml, lì è possibile utilizzare require qualsiasi momento si desidera

Codice in renderer.jshttps://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 
}) 

Codice in htmlhttps://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>