body.onload и порядок запуска GWT onModuleLoad - PullRequest
3 голосов
/ 07 ноября 2011

Согласно этому FAQ , когда GWT загружается, onModuleLoad должен запускаться до события onload тела HTML. Процесс, описанный в этом 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.

Но в своих тестах я проверил, что это не работает таким образом. Или, по крайней мере, не в каждом браузере (как ни странно, 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 не может его использовать.

А чего я пытаюсь достичь? Я хочу, чтобы какой-то рукописный Javascript, работающий в body.onload, взаимодействовал с моим GWT-кодом. В этом примере я использую этот фиктивный «загруженный» var, но в будущем он сможет вызывать функции GWT, написанные на Java. Проблема в том, что мне нужно убедиться, что onModuleLoad запускается первым, чтобы он мог экспортировать переменные и методы для доступа к ним javascript.

Итак, что мне не хватает? Это поведение так ненадежно, как кажется, или я делаю что-то не так?

PS: у меня есть план B для достижения этого, который доказал свою работоспособность, но сначала я хочу убедиться, что это невозможно сделать, так как это должен быть предпочтительный метод.

1 Ответ

3 голосов
/ 07 ноября 2011

Во-первых, последняя версия документа находится на 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, но зачем ждать?)

...