0

我有 SWT 应用程序,它使用地图服务 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.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;
}

编辑2

经过一些更深入的调试后,从地图层中删除控件的方法是

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调用允许另一个执行的“线程”赶上。

因此,您可能想查看代码执行的顺序,例如使用console.logthroughout 进行跟踪。

于 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 回答