【问题标题】:setAbstractView() prevents mousedown events from propagating to KmlFeaturessetAbstractView() 防止 mousedown 事件传播到 KmlFeatures
【发布时间】:2013-10-17 23:54:17
【问题描述】:

使用 Google 地球插件,我希望能够允许用户在相机移动时选择地面上的地标,但我不确定这是如何实现的。似乎当您调用 setAbstractView() 时,即使将 flyToSpeed 设置为 SPEED_TELEPORT,Google 地球插件也会忽略除 GEGlobe 之外的任何鼠标按下事件。

这是代码,稍作改动(来自http://code.google.com/apis/ajax/playground/#draggable_placemark)以说明我的问题:

var ge;

var placemark;
var dragInfo = null;
var la;
var lat = 37;
var lon = -122;

google.load("earth", "1");

function init() {
  google.earth.createInstance('map3d', initCallback, failureCallback);
}

function tick() {
  la.set(lat, lon,
    0, // altitude
    ge.ALTITUDE_RELATIVE_TO_GROUND,
    0, // heading
    0, // straight-down tilt
    5000 // range (inverse of zoom)
    );
  ge.getView().setAbstractView(la);
  lon = lon + 0.00000001;
}

function initCallback(instance) {
  ge = instance;
  ge.getWindow().setVisibility(true);

  // add a navigation control
  ge.getNavigationControl().setVisibility(ge.VISIBILITY_AUTO);

  // add some layers
  ge.getLayerRoot().enableLayerById(ge.LAYER_BORDERS, true);
  ge.getLayerRoot().enableLayerById(ge.LAYER_ROADS, true);

  // create the placemark
  placemark = ge.createPlacemark('');

  var point = ge.createPoint('');
  point.setLatitude(lat);
  point.setLongitude(lon);
  placemark.setGeometry(point);

  // add the placemark to the earth DOM
  ge.getFeatures().appendChild(placemark);

  // look at the placemark we created
  la = ge.createLookAt('');
  placemark.setName('Drag Me!');
  ge.getOptions().setFlyToSpeed(ge.SPEED_TELEPORT);
  tick();

  // Comment this next line out and the drag works as expected.
  google.earth.addEventListener(ge, "frameend", tick);

  // listen for mousedown on the window (look specifically for point placemarks)
  google.earth.addEventListener(ge.getWindow(), 'mousedown', function(event) {
    console.log("target type = " + event.getTarget().getType());
    if (event.getTarget().getType() == 'KmlPlacemark' &&
        event.getTarget().getGeometry().getType() == 'KmlPoint') {
      //event.preventDefault();
      var placemark = event.getTarget();

      dragInfo = {
        placemark: event.getTarget(),
        dragged: false
      };
    }
  });

  // listen for mousemove on the globe
  google.earth.addEventListener(ge.getGlobe(), 'mousemove', function(event) {
    if (dragInfo) {
      event.preventDefault();
      var point = dragInfo.placemark.getGeometry();
      point.setLatitude(event.getLatitude());
      point.setLongitude(event.getLongitude());
      dragInfo.dragged = true;
    }
  });

  // listen for mouseup on the window
  google.earth.addEventListener(ge.getWindow(), 'mouseup', function(event) {
    if (dragInfo) {
      if (dragInfo.dragged) {
        // if the placemark was dragged, prevent balloons from popping up
        event.preventDefault();
      }

      dragInfo = null;
    }
  });

  document.getElementById('installed-plugin-version').innerHTML =
    ge.getPluginVersion().toString();
}

function failureCallback(errorCode) {
}

​ 如果您注释掉第 56 行,其中在每个帧结束处调用了 tick(),则一切都与未更改的代码中一样:您可以成功拖动地标。但是当第 56 行进入时,你不能。所以问题实际上在于 setAbstractView 阻止 mousedown 事件传播到地球或任何被点击的地标或功能。

有什么想法吗?有解决方法吗?

【问题讨论】:

  • 只是想确定它是否与错误有关 - 哪些浏览器会显示此行为?
  • 我已经在 Safari、Firefox 和 Chrome 中复制了它,并鼓励其他人也尝试一下。只需将代码块复制并粘贴到 Google Code Playground:code.google.com/apis/ajax/playground/#draggable_placemark

标签: javascript kml google-earth-plugin


【解决方案1】:

该问题不是setAbstractView方法引起的,而是通过framend重复调用tick方法引起的。

为了解释,您已将tick 方法设置为frameend 事件的事件处理程序。 然后tick方法立即更新视图,触发frameend事件,无限循环……

这种模式会导致浏览器消息循环出现问题,实际上它会阻止其他拖动事件。把它想象成一个导致死锁的非常紧密的循环。要使用它,您可以使用值为 0 的setTimeout 来执行代码。这样,在处理所有其他待处理的拖动消息之前,不会处理动画。

关键部分是对 tick() 方法的修改。

function tick() {
  // prevent deadlock
  setTimeout(function () {
    la.set(lat, lon, 0, ge.ALTITUDE_RELATIVE_TO_GROUND, 0, 0, 5000);
    ge.getView().setAbstractView(la);
    lon += 0.00001;
  }, 0);
};

在这里,我为你做了一个完整的例子http://jsfiddle.net/fraser/JFLaT/

我对其进行了测试,它可以在 Windows 8 上的 Chrome、IE、Firefox 和 OSX 上的 Chrome、Safari、Firefox 中运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-30
    • 1970-01-01
    • 2011-01-04
    相关资源
    最近更新 更多