背景
在Electron打開新窗口的時候,提前加載一段JavaScript腳本,以此內置一些屬性或接口給被打開的頁面。之所以要以注入方式,而不是頁面自己引用,原因是不想麻煩頁面自行引用,不想修改舊有的業務邏輯。
方法一
一開始是想在打開BrowserWindow后,執行executeJavaScript方法來給相應的窗口注入腳本。
不過這個方法雖然可以在相應的窗口注入腳本,但是它的執行的順序太后,無法在頁面加載時加載到,就導致了如果頁面的在加載時使用了注入接口,就會有調用不到問題。
所以這個方法不可行。
PS:executeJavaScript方法,https://electronjs.org/docs/api/web-contents
方法二
后來我在new BrowserWindow([options])方法,也就是新建窗口的方法找到了一個preload參數。
const { BrowserWindow } = require('electron') const path = require('path') const renderProcessApi = path.join(__dirname, './inject.js') let win = new BrowserWindow({ webPreferences: { preload: renderProcessApi } })
這個腳本文件,會在頁面加載資源前就加載執行,保證了頁面無論是在什么地方、什么時候調用注入接口都能調用到。
特別注意
如果窗口是在主進程創建的,估計有人就會發現注入的腳本文件會在主進程和對應的渲染進程各執行了一遍(我也不清楚為什么會有這樣的效果)。
這時有可能會導致打開窗口失敗,因為注入腳本中使用的對象或方法是主進程沒有的,例如window對象。
解決辦法是得判斷腳本是在渲染進程時,才執行腳本內容。
inject.js文件:
if (require('electron').remote) { window.hello = function(){ console.log(‘world') } }
可以通過require('electron').remote,來判斷是否在渲染進程。