Electronにはウィンドウオープン時のpreloadオプションとかexecuteJavaScript
関数とかの、Javascriptを埋め込んで実行する便利機能がありますが、他のイベントと併せてこいつらはどういう順番で実行されるの? と混乱してきたので実験してみました。
#テストプログラム
- main.jsからindex.htmlを開く
- index.htmlのpreloadオプションにpreload_index.jsを指定
- index.html内にwebviewタグでwebview.htmlを読み込む
- webview.htmlのpreloadにpreload_webview.jsを指定
イベントが発生したら、ipcでメインプロセスにメッセージを送信し、それを表示しています。
イベントの発生順にconsole.logにメッセージが表示されるはずです。
main.js
'use strict';
const {app, BrowserWindow, ipcMain} = require('electron');
const path = require('path');
let mainWindow = null;
app.on('window-all-closed', ()=>app.quit());
let webContentJs = `
let ipcRender = require('electron').ipcRenderer;
ipcRender.send('ipc', 'WebContents.executeJavaScriptで実行されたJavascript');`;
app.on('ready', function() {
mainWindow = new BrowserWindow({
webPreferences: {
preload: path.resolve(path.join(__dirname, 'preload_index.js')),
},
});
mainWindow.loadURL(`file://${__dirname}/index.html`);
mainWindow.webContents.executeJavaScript(webContentJs);
mainWindow.webContents.on('did-finish-load', ()=> console.log('WebContents.did-finish-loadイベント'));
mainWindow.webContents.on('did-start-loading', ()=> console.log('WebContents.did-start-loadingイベント'));
mainWindow.webContents.on('dom-ready', ()=> console.log('WebContents.dom-readyイベント'));
ipcMain.on('ipc', (event, arg)=> console.log(arg));
mainWindow.on('closed', ()=> mainWindow = null);
mainWindow.webContents.openDevTools({mode:'undocked'});
});
index.html
<!DOCTYPE html>
<!-- メインウィンドウ-->
<html lang="ja">
<head>
<meta charset="utf-8" />
<script>
const {ipcRenderer} = require('electron');
ipcRenderer.send('ipc', 'index.html内の<script>タグ');
window.addEventListener('load', function() {
ipcRenderer.send('ipc', 'index.htmlのwindow.onload');
});
</script>
</head>
<body>
てすと<br>
<webview class="wv" src="webview.html" preload="./preload_webview.js"></webview>
</body>
</html>
preload_index.js
//" a script that will be loaded before other scripts run in the page."
const {ipcRenderer} = require('electron');
window.addEventListener('load', ()=> ipcRenderer.send('ipc', 'index.htmlのpreloadのwindow.onload'));
ipcRenderer.send('ipc', 'index.htmlのpreload');
webview.html
<!DOCTYPE html>
<!--index.html内に読み込まれるwebview-->
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>webview</title>
</head>
<body>
webview<br>
</body>
</html>
preload_webview.js
const {ipcRenderer} = require('electron');
window.addEventListener('load', ()=> ipcRenderer.send('ipc', 'webview.htmlのpreloadのwindow.onload'));
ipcRenderer.send('ipc', 'webview.htmlのpreload');
#実行結果
こんな感じになりました。
index.htmlのpreload
index.html内の<script>タグ
WebContents.dom-readyイベント
index.htmlのpreloadのwindow.onload
index.htmlのwindow.onload
WebContents.did-finish-loadイベント
WebContents.executeJavaScriptで実行されたJavascript
webview.htmlのpreload
webview.htmlのpreloadのwindow.onload
WebContents.did-start-loadingは発生しないんですね。
リロードしてみました。
WebContents.did-start-loadingイベント
index.htmlのpreload
index.html内の<script>タグ
WebContents.dom-readyイベント
index.htmlのpreloadのwindow.onload
index.htmlのwindow.onload
WebContents.did-finish-loadイベント
webview.htmlのpreload
webview.htmlのpreloadのwindow.onload
webviewのpreloadは、WebContents.did-finish-loadingより先に実行されるかと思っていました。
しかもリロード時は、executeJavascriptは実行されないんですね。
実験してみるものですね。