2011-11-07 46 views
3

根據this FAQ,當GWT引導時,onModuleLoad被放置在HTML主體的onload事件之前運行。該FAQ中詳細描述的過程是這樣的:body.onload和GWT onModuleLoad發佈訂單

1. The HTML document is fetched and parsing begins. 
... 
9. externalScriptOne.js completes. The document is ready, so onModuleLoad() fires. 
... 
12. body.onload() fires, in this case showing an alert() box. 

但在我的測試中,我已經檢查了它不以這種方式工作。或者至少不是在每個瀏覽器中(奇怪的是,谷歌瀏覽器並不堅持這種行爲)。例如,我有這個小測試涉及onModuleLoad和body.onLoad:

public void onModuleLoad() { 

    runTestFunction(); 

} 

private native void runTestFunction() /*-{ 
    console.log("GWT's onModuleLoad"); 
    $wnd.loaded=true; 
}-*/; 

和:

<body onload="console.log('body.onLoad');if(loaded!=null) console.log('loaded var is set');"> 

如果我啓動Firefox和運行這個例子,控制檯將顯示此:

GWT's onModuleLoad 
body.onLoad 
loaded var is set 

但在Chrome:

body.onLoad 
Uncaught ReferenceError: loaded is not defined 
GWT's onModuleLoad 

在後者中,onModuleLoad運行最後一個,因此「已加載」var尚不可用,body.onLoad代碼無法使用它。

而我試圖實現什麼?我想要一些在body.onload中運行的手寫Javascript與我的GWT代碼進行交互。在這個例子中,我使用這個虛擬的「loaded」var,但將來它應該能夠調用用Java編寫的GWT函數。問題是我需要確保onModuleLoad首先運行,以便它可以導出javascript的變量和方法來訪問它們。

所以,我失去了什麼?這種行爲看起來像不可靠,還是我做錯了什麼?

PS:我有一個B計劃,以實現這一目標被證明可行,但首先我想確保它不是可以做這種方式,因爲這應該是首選的方法。

回答

3

首先,美國商務部的最新版本是在http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideBootstrap

它說(即使是GWT 1.5版本,你在看)認爲,「onModuleLoad()可以在任何時候被稱爲外部文件已經經過解析「,其中包括window.onload之前和之後。

正如文檔所述,GWT將你的代碼加載到iframe中(這裏用作沙箱),它是異步的;所以當你加載iframe和「body」時你的代碼會被加載。根據加載iframe所需的時間,可以在window.onload之前或之後(在本例中,它們假設它立即加載,當*.cache.*文件在瀏覽器的緩存中有效時可能會發生這種情況)。

但是經驗法則是,GWT努力(至少內置鏈接器)使事情異步啓動,以便它不會中斷其他外部資源(例如樣式表和圖像)的加載。這意味着,它不能保證之前運行window.onload(他們可以保證window.onload後運行,但爲什麼還要等待?)

+0

所以,它不是可靠的出口GWT方法onModuleLoad的變量是什麼呢?那麼你會把出口商放在哪裏?換句話說,如何確保某些手寫的JS只在出口已經發生時才能運行? –

+0

完成後,您的GWT模塊是否調用全局函數;或多或少像(m)任何腳本注入器。請參閱http://code.google.com/p/gwtchismes/wiki/Tutorial_ExportingGwtLibrariesToJavascript_en#Using_GWT-exporter作爲一個很好的例子(使用[GWT exporter](http://code.google.com/p/gwt-exporter/)使用註釋將GWT代碼導出到JavaScript)。 –