GWTのページには複数のモジュールが含まれています.

2941 ワード

GTバージョン:1.4.61
ブラウザバージョン:IE 6
一つのページに複数のGWTモジュールが含まれている場合、マウスイベント(主にmouseoverイベント)が発生した場合、IEはjavascriptエラーを報告します.Object doesn't support this property or method.テスト後、GTコンパイル時に混淆を使わないとエラーが発生しません.
ウェブ検索と自己分析によると、この問題は主にGWTのブラウザイベント管理機構が複数のGWTモジュール間で衝突したためである.
GWTのウェブサイトでは間違いの事例が提供されています.以下のURLで説明と事例ダウンロードが見つかります.
Issue 1804:    JavaScript Errers generanted on mouse events with 2 Modules on 1 Page
このケースのダウンロードも添付します.またGWTサイトの他のページでも関連する議論と解決策がある.
JavaScript Error on Mouse Events with 2 Modules on 1 Pageオプション
Issue 1788:    Only the last module to call DOMImplStandard.init()is able to preview events 
Issue 1546:    Eliminate DOM modifications to body element
まずGWTのイベントハンドリングの仕組みについて説明します.GWTモジュール内のすべてのイベントは$wnd.u.u.に登録されます.dispatch Event関数は、一つのページに複数のモジュールが存在すると、各モジュールは自分のコンポーネントのイベントを自分の定義した‘u_’に登録します.dispatch Event関数です.

$doc.body.onclick = $doc.body.onmouseover = ... = $wnd.__dispatchEvent;

element.onclick = bits & 1 ? $wnd.__dispatchEvent : null;
...
element.XXX = bits & XX ? $wnd.__dispatchEvent : null;
//bits              ,             ,
//         ( onclick 1)              。
事件発生後、実行する.dispatch Event関数:

var listener, cureElem = this;
while (curElem && !(listener = curElem.__listener))
    curElem = curElem.parentElement;
if (listener)
    com_google_gwt_user_client_DOM_dispatchEvent_Lcom_googel_gwt_user_client_Event_2Lcom_google_gwt_user_client_Element_2Lcom_google_gwt_user_client_EventListener_2($wnd.event, curElem, listener);
listenerが存在すると、最終的に次のコードに呼び出されます.

listener.onBrwoserEvent__Lcom_google_gwt_user_client_Event_2(evt);
本来はモジュール間のコードは2段とも一致していますので、複数のコードが定義されていてもdispatch Event方法も大丈夫です.問題は混淆後、モジュール別のコンポーネントの_u u u uです.listener属性対象のオンブリーゼイベントルコム.googlegwt_アメリカ.clientイベント2関数は異なる名前に混同されます.例えば、最初のモジュールはa関数、二つ目はb関数です.このように複数のモジュールが1ページにある場合、最初のモジュールの1つのコンポーネントのイベントが発生した後に、2番目のモジュールで定義されるかもしれない.dispatch Event関数で処理した結果、b関数が呼び出されましたが、この関数は最初のモジュールのコンポーネントのlistener属性オブジェクトに存在しません.この時はjavascriptエラーが発生します.Object doesn't support this property or method(対象はこの属性または方法をサポートしていません).これはコードを混同しない時は間違えないということです.
なぜ複数のモジュール間のコンポーネントイベントの登録が衝突するのか、この問題はまだ分かりません.現在のテスト結果は、すべての状況ではないということを示しています.いくつかの特殊な状況でしか現れないです.暇があれば、添付したテストケースの分析を本文に補足します.