根据this FAQ,当GWT引导时,onModuleLoad被用来在HTML body的onload事件之前运行。该FAQ中详述的流程如下:
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.
但是在我的测试中,我已经检查过它不会以这种方式工作。或者至少不是在每个浏览器中(奇怪的是,谷歌Chrome特别不坚持这种行为)。例如,我有一个涉及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代码进行交互。在这个例子中,我使用这个虚拟的“加载”var,但将来它应该能够调用用Java编写的GWT函数。问题是我需要确保onModuleLoad首先运行,以便它可以导出javascript的变量和方法来访问它们。
那么,我错过了什么?这种行为看起来像是不可靠的,还是我做错了什么?
PS:我有一个计划B来实现这一点,事实证明这是有效的,但首先我要确保不可能这样做,因为这应该是首选的方法。
答案 0 :(得分: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
之后运行,但为什么要等?)