0

マップサービスAPI(特にhttp://mapy.cz)を使用して、提供されたマップデータに基づいていくつかの追加の図面の背景として画像を取得するSWTアプリケーションがあります。

ブラウザコンポーネントのスクリーンショットがSWTGCインスタンスによって作成される前に、可能な限りクリーンにするために、マップレイヤーからコントロールを非表示にしようとしています。この機能は、サービスのJSAPIによって次のように提供されます。

function hideControls() {
    var controls = map.getControls();
    for (var i = controls.length; i > 0; i--) {
        map.removeControl(controls[i]);
    }
    //alert('test');
}

これは、コンソールから関数を呼び出すことにより、すべてのデスクトップブラウザで完全に機能します。hideControls()

ただし、メソッドがSWTブラウザコンポーネントによって呼び出された場合

browser.evaluate("hideControls();"); 

alert()関数(現在コメントされている)のコメントが解除されるまで機能しません。次に、アラートダイアログが表示され、コントロールが非表示になります。

alert()メソッド呼び出しがそのJavaScript関数の正しい動作を引き起こす理由は何ですか?

編集

いくつかの追加のコードコンテキスト

browser.evaluate("hideControls();");
// ugly ie scroll bar force workaround
// calls JS methods which returns size of map content in browser component
Double mapWidth = (Double) browser.evaluate("return getSizeX();");
Double mapHeight = (Double) browser.evaluate("return getSizeY();");
// creates new canvas
GC gc = new GC(browser);
// do the screenshot
capturedImage = new Image(display, mapWidth.intValue(), mapHeight.intValue());
gc.copyArea(capturedImage, 0, 0);
// cleanout
gc.dispose();

マップサイズ計算用のJavaScriptメソッド(マップサービス用にJS APIによって提供されます)

function getSizeX() {
    return map.getSize().x;
}
function getSizeY() {
    return map.getSize().y;
}

EDIT2

いくつかのより深いデバッグの後、マップレイヤーからコントロールを削除する方法は次のとおりです。

SMap.prototype.removeControl = function (a) {
    var b = this.controls.indexOf(a); 
    - 1 != b && ((a = a.getContainer()) && this.controlLayer.removeItem(a), this.controls.splice(b, 1))
};

たとえば(HUD制御用)

SMap.Layer.HUD.prototype.removeItem = function (a) {
    a.parentNode.removeChild(a)
};

つまり、非同期ではありませんが、DOMツリーを直接変更します。

4

2 に答える 2

1

これalertは、ここで目に見える効果があり、競合状態が発生している方向を示しています。そこでは、ブロッキングalert呼び出しにより、実行の他の「スレッド」が追いつくことができます。

そのため、たとえば through を使用console.logしてトレースするなど、コードが実行される順序を確認することをお勧めします。

于 2013-01-31T19:10:22.597 に答える
0

Sean Kinsey がほのめかしたように、これは実際にはブラウザー コンポーネントの問題であり、JavaScript スレッドが必要なすべてのステップを完了するまで停止する必要があります。

私は回避策を見つけました。SWT GUI コンポーネントでは、イベント処理自体を処理する必要があるため、JavaScript が終了するまでブラウザーを停止させることは可能ですが。

browser.evaluate("hideControls();");
for(int i = 0; i < 20; i++) {
    if(!display.readAndDispatch()); display.sleep();
}

これは醜い回避策ですが、ブラウザが些細な DOM 操作を行うには 20 の「ティック」で十分なはずです (願っています)。

于 2013-02-01T08:39:06.680 に答える