背景 在Electron打開新視窗的時候,提前載入一段JavaScript腳本,以此內置一些屬性或介面給被打開的頁面。之所以要以註入方式,而不是頁面自己引用,原因是不想麻煩頁面自行引用,不想修改舊有的業務邏輯。 方法一 一開始是想在打開BrowserWindow後,執行executeJavaScri ...
背景
在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,來判斷是否在渲染進程。