由alert()修复的JavaScript方法处理

时间:2013-01-31 17:48:05

标签: javascript swt

我有SWT应用程序使用map service API(特别是http://mapy.cz)获取图像作为基于提供的地图数据的一些附加图纸的背景。

在SWT GC实例制作浏览器组件截图之前,我试图隐藏地图图层中的控件,以尽可能保持最清晰。此功能由服务的JS API以这种方式提供:

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

通过从控制台调用hideControls()函数,在所有桌面浏览器中完美无瑕

但是如果该方法由SWT Browser组件调用

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树,虽然它不是异步的。

2 个答案:

答案 0 :(得分:1)

alert在这里有一个明显的效果,指向你有一个竞争条件的方向,阻塞alert调用允许执行的另一个'线程'赶上来。

因此,您可能需要查看代码执行的顺序,例如在整个跟踪过程中使用console.log

答案 1 :(得分:0)

正如Sean Kinsey所暗示的那样,浏览器组件确实存在问题,在JavaScript线程完成所有必要步骤之前,需要停止运行。

我找到了解决方法,因为SWT GUI组件必须自己处理事件处理,尽管可能会停止浏览器直到JavaScript完成。

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

这是一个丑陋的解决方法,但浏览器做一些简单的DOM操作的20'滴答应该就足够了(我希望)。