web-dev-qa-db-fra.com

Comment appeler une fonction JavaScript sur une page web rendue par Electron?

J'essaie d'écrire un wrapper pour Twitter en utilisant Electron (anciennement Atom Shell).

Mon fichier main.js (Il ressemble presque à l'exemple " Hello World ", je viens de le changer en un seul endroit):

var app = require('app');  // Module to control application life.
var BrowserWindow = require('browser-window');  // Module to create native browser window.

// Report crashes to our server.
require('crash-reporter').start();

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the javascript object is GCed.
var mainWindow = null;

// Quit when all windows are closed.
app.on('window-all-closed', function() {
  if (process.platform != 'darwin')
    app.quit();
});

// This method will be called when atom-Shell has done everything
// initialization and ready for creating browser windows.
app.on('ready', function() {

  // Create the browser window.
  mainWindow = new BrowserWindow ({'width':1000,'height':600});
  // and load the index.html of the app.
  mainWindow.loadUrl('https://Twitter.com');

  // Emitted when the window is closed.
  mainWindow.on('closed', function() {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null;
  });
});

J'essaie d'appeler la fonction alert() juste après mainWindow.loadUrl() mais elle ne s'exécute pas.

Je comprends que le fichier main.js Est comme le côté serveur de mon application, mais la question est ... Comment puis-je appeler une fonction JavaScript sur la page? Où dois-je écrire le code?

Par exemple, je veux effectuer ceci:

$(document).ready(function() {
    alert("Hurray!");
});
15
evlogii

J'ai résolu le problème. Voici l'exemple de code:

...

app.on('ready', function() {

  ...

  mainWindow.webContents.on('did-finish-load', function() {
    mainWindow.webContents.executeJavaScript("alert('Hello There!');");
  });

  ...

});
22
evlogii

Tout d'abord, vous devriez voir clairement la différenciation des processus au sein d'Electron (anciennement Atom Shell). Electron utilise le processus principal comme une sorte de back-end (vous pouvez l'appeler " côté serveur" comme vous le faites) et un point d'entrée de votre application. Comme vous le savez probablement, le processus principal peut générer plusieurs instances de BrowserWindow, qui sont en fait des fenêtres de système d'exploitation distinctes hébergeant chacune une page Web rendue Chromium exécutée dans un processus séparé appelé processus de rendu . Vous pouvez considérer le processus de rendu comme une simple fenêtre de navigateur avec des capacités potentiellement étendues, comme l'accès aux modules Node.js (j'écris " potentiellement", car vous pouvez désactiver l'intégration Node.js pour le processus de rendu ).

Il convient de mentionner que, bien que vous ayez une fenêtre avec une interface graphique pour le processus de rendu, vous n'en avez pas pour le processus principal. En fait, cela n'a pas beaucoup de sens d'en avoir un pour la logique principale de votre application. Il n'est donc pas possible d'appeler alert() directement dans le processus principal et de voir la fenêtre d'alerte. La solution que vous avez proposée montre bien l'alerte. Mais il est important de comprendre que la fenêtre contextuelle est créée par le processus de rendu et non par le processus principal lui-même! Le processus principal demande simplement au moteur de rendu d'afficher l'alerte (c'est ce que fait réellement la fonction webContents.executeJavaScript).

Deuxièmement, si je comprends bien ce que vous essayez vraiment de réaliser ici en appelant la fonction alert() dans le processus principal, c'est le traçage de l'exécution du programme. Vous pouvez appeler console.log() pour envoyer le message souhaité à la console. Dans ce cas, l'application elle-même doit être lancée à partir de la console:

/path/to/electron-framework/electron /your/app/folder

Maintenant, ce qui est encore mieux, c'est que vous pouvez déboguer le processus principal. Pour ce faire, l'application doit être démarrée avec la touche --debug (Ou --debug-brk) Et la valeur du port d'écoute qui lui est affecté. Juste comme ça:

/path/to/electron-framework/electron --debug=1234 /your/app/folder

Vous pouvez utiliser n'importe quel type de débogueur V8 pour vous connecter au port affecté et démarrer le débogage. Cela signifie que théoriquement tout débogueur Node.js doit fonctionner. Jetez un œil à node-inspector ou débogueur WebStorm . Il y a une question populaire ici à StackOverflow sur le débogage des applications Node.js: Comment puis-je déboguer les applications Node.js? .

12

La manière appropriée consiste à utiliser contents.send('some_js_Method','parameters') pour appeler une méthode javascript dans une page Web à partir de main.js

// In the main.js
const {app, BrowserWindow} = require('electron')
let win = null

app.on('ready', () => {
  win = new BrowserWindow({width: 800, height: 600})
  win.loadURL(`file://${__dirname}/index.html`)
  win.webContents.send(some_js_Method', 'window created!') //calling js method (async call)
})


//in index.html
<html>
<body>
  <script>
    require('electron').ipcRenderer.on('some_js_Method', (event, message) => {
      console.log(message)  // Prints 'window created!'
    })
  </script>
</body>
</html>
2
JerryGoyal