我有一個Greasemonkey腳本,可以在Firefox和Opera中正常工作。然而,我努力讓它在Chrome中運行。問題是將一個函數注入到頁面中的代碼可以調用的頁面中。這是我到目前爲止所做的:在Chrome上從Greasemonkey腳本將JS函數注入頁面
首先,我得到Firefox的unsafeWindow的幫手參考。這允許我爲FF和Opera(和Chrome,我想)提供相同的代碼。
var uw = (this.unsafeWindow) ? this.unsafeWindow : window;
接下來,我向頁面中注入一個函數。這真的只是一個很薄的包裝,什麼也不做,但在我的GM腳本的上下文中調用相應功能:
uw.setConfigOption = function(newValue) {
setTimeout(setConfigOption, 0, newValue);
}
然後,有相應的功能就在我的腳本:
setConfigOption = function(newValue) {
// do something with it, e.g. store in localStorage
}
末,我用一個鏈接來注入一些HTML到頁面來調用函數。
var p = document.createElement('p');
p.innerHTML = '<a href="javascript:setConfigOption(1)">set config option to 1</a>';
document.getElementById('injection-point').appendChild(p);
總結: 在Firefox中,當注入鏈接的用戶點擊,它將執行上unsafeWindow,然後觸發調用相應的功能在我的GM腳本的上下文超時的函數調用,然後進行實際處理。 (糾正我,如果我在這裏錯了。)
在Chrome中,我剛剛得到一個「未捕獲的ReferenceError:setConfigOption未定義」錯誤。事實上,在控制檯中輸入「window.setConfigOption」會產生「未定義」。在Firebug和Opera開發者控制檯中,函數就在那裏。
也許還有另一種方法可以做到這一點,但我的一些功能是由頁面上的Flash對象調用的,我相信這使我有必要在頁面上下文中有功能。
我快速瀏覽了Greasemonkey wiki上的alternatives to unsafeWindow,但它們都顯得很醜陋。我在這裏完全走錯了路,還是應該仔細觀察這些?
解決方案:我遵循Max S.' advice,它現在可以在Firefox和Chrome中使用。因爲我需要爲頁面提供的函數必須回調到常規函數中,所以我將整個腳本移動到頁面,即完全包裝到他稱爲「main()」的函數中。
爲了讓這種黑客變得更加尷尬,我現在至少可以放棄使用unsafeWindow和wrappedJSObject。
我還沒有設法讓Greasemonkey wiki上的content scope runner正常工作。它應該做同樣的事情,它似乎執行得很好,但我的功能從不可訪問頁面中的<a>
元素,例如。我還沒有弄清楚爲什麼。
我試過'content scope runner'(如果我沒有弄錯的話,確實如此),並且當函數可用於我的腳本時,它們似乎不可用於頁面(例如錨標籤)。你有任何示例代碼或任何你可以鏈接到? 我並不十分在意執行的順序。當我設法從頁面調用一個注入函數時,我可以解決這個問題。 :) – 2010-02-20 19:37:41
內容腳本執行的順序可以通過'run_at'語句來定義http://code.google.com/chrome/extensions/content_scripts.html – NVI 2010-02-20 20:27:24
re run_at:我沒有寫一個Chrome擴展,儘管(和我不打算過多地維護兩個腳本)。這只是一個Greasemonkey腳本,我試圖做足夠的兼容性,以便Chrome可以將GM腳本「自動轉換」爲擴展名。 – 2010-02-20 20:32:25