2015-03-07 2 views
9

Я пытаюсь написать обертку для Twitter с использованием Electron (ранее Atom Shell).Как вызвать функцию JavaScript на веб-странице, предоставленной Electron?

Мой main.js файл (он выглядит почти идентично примеру «Hello World», я просто изменил его в одном месте):

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

Я пытаюсь вызвать alert() функцию сразу после mainWindow.loadUrl() но не выполняет.

Я понимаю, что файл main.js похож на серверную часть моего приложения, но вопрос в том, что ... Как я могу вызвать функцию JavaScript на странице? Где я должен писать код?

Например, я хочу, чтобы выполнить это:

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

ответ

15

Я решил эту проблему. Вот пример кода:

... 

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

    ... 

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

    ... 

}); 
+4

Хотя код, который вы предложили показывает предупреждение, вы должны четко понимать, почему главный процесс хочу спросите 'mainWindow' (процесс визуализации), чтобы отобразить предупреждение. Я думаю, что разделение проблем между основным процессом и рендерингом является довольно важным вопросом здесь. По этой причине контроль над пользовательским интерфейсом процесса визуализации от основного процесса, скорее всего, следует избегать. Если ваша главная цель с 'alert()' была трассировкой 'main.js', вы можете прочитать мой ответ на этот вопрос. Там отмечаются некоторые другие методы отладки. –

+1

@ KonstantinGrushetsky, очень хороший момент, я бы поднял вас два раза, если бы мог;) – Konstantin

11

Прежде всего, вы должны четко видеть дифференциацию процессов внутри Electron (ранее Atom Shell). Electron использует основной процесс как своего рода фоновый (вы можете назвать его «» стороной сервера «как и вы») и точкой входа приложения. Как вы, вероятно, понимаете, что основной процесс может порождать несколько экземпляров BrowserWindow, которые на самом деле являются отдельными окнами операционной системы, каждый из которых размещает веб-страницу, обработанную Chromium, в отдельном процессе с именем процесс визуализации. Вы можете рассматривать процесс визуализации как простое окно браузера с потенциально расширенными возможностями, например, доступ к модулям Node.js (я пишу «потенциально», потому что вы можете отключить интеграцию Node.js для процесса визуализации).

Следует отметить, что, хотя у вас есть окно с графическим интерфейсом для процесса рендеринга, у вас нет основного процесса. На самом деле, это не имеет большого смысла, чтобы иметь один для внутренней логики вашего приложения. Таким образом, невозможно вызвать alert() непосредственно в основном процессе и посмотреть окно предупреждения. Решение, которое вы предложили, действительно показывает предупреждение. Но важно понимать, что всплывающее окно создается процессом рендеринга, а не основным процессом! Основной процесс просто просит визуализатор показать предупреждение (вот что делает функция webContents.executeJavaScript).

Во-вторых, поскольку я понимаю, чего вы действительно пытаетесь достичь здесь, с вызовом alert() Функция в основном процессе - это трассировка выполнения программы. Вы можете позвонить console.log(), чтобы вывести нужное сообщение на консоль. В этом случае само приложение должно запускаться из консоли:

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

Теперь, что еще лучше, что вы можете отлаживать основной процесс. Для этого приложение должно быть запущено с помощью ключа (или --debug-brk) и назначенного ему порта прослушивания. Просто так:

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

Вы можете использовать любой вид V8 debugger прикрепить к заданному порту и запустить отладку. Это означает, что теоретически любой отладчик Node.js должен работать. Взгляните на node-inspector или WebStorm debugger.В StackOverflow есть популярный вопрос об отладке приложений Node.js: How do I debug Node.js applications?.

+0

Привет @Toxic, как я могу вызвать app.quit() из процесса рендеринга? –

+0

@ DeepakThomas, вам нужно сначала отправить событие в основной процесс и выйти из него. Но это, очевидно, отдельный вопрос. – Konstantin

+0

@ konstantin Yup :) Спросил об этом, когда я был noob для Electron. Спасибо за ваш ответ! –

0

собственно способ заключается в использовании contents.send('some_js_Method','parameters') для вызова яваскрипта метод на веб-странице с 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>