根据this FAQ的描述,当GWT引导时,可以假设onModuleLoad在HTML主体的onload事件之前运行。该常见问题解答中详细介绍的过程如下:
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.
但是在我的测试中,我检查了它是否不能以这种方式工作。或至少不是在所有浏览器中都(尤其是Google 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代码进行交互。在此示例中,我使用了这个虚拟的“loaded”变量,但将来它应该能够调用用Java编写的GWT函数。问题是我需要确保onModuleLoad首先运行,以便它可以导出变量和方法以供javascript访问它们。
所以,我想念什么?这种行为是否像看起来那样不可靠,还是我做错了什么?
PS:我有一个计划B来实现这一目标,事实证明是可行的,但是首先我想确保不可能以这种方式进行,因为这应该是首选方法。
最佳答案
首先,该文档的最新版本位于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
之后运行,但是为什么要等待?)
关于gwt - body.onload和GET在模块加载启动顺序上,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8035656/