谷歌地图API v3:标记未被移除

9
我正在创建一个地图,根据边界框和缩放级别加载和销毁标记。我遇到了一个真正的问题,无法正确地删除标记,有时似乎对某些情况起作用。
我有一个包含标记信息的对象,该对象还包含Google地图标记对象。我的代码检测是否应该根据边界框或缩放级别删除市场。我将标记对象设置为“setMap(null);”,并使用Firebug可以看到它正在被设置,然后我完全删除父对象,并且对象数据长度正确更新。
当标记被删除时,我输出到Firebug控制台,似乎正在工作,我可以看到标记没有从边界框更改的标记ajax调用中重新创建。
然而,如果我在地图周围缩放,有时会看到标记被删除,如果我缩小然后再次按住鼠标回来。或者有时,如果我第一次缩小,所有标记都将被删除,但是如果我再次缩小然后再次缩小,则不会删除它们。
我的代码逻辑肯定有问题,我束手无策。
你可以查看以下链接的源代码: http://www.trailforks.com/map/test.php?lat=49.352247&lon=-123.202413 相关JS代码在这里: http://www.trailforks.com/map/includes/map.js 删除标记的代码位于底部。
function clearMarkerMemory(mapItem, i) {
  google.maps.event.removeListener(mapItem.lis);    // remove stored listener

  mapper.data[i].obj.setMap(null); // remove marker
  mapper.data.splice(i, 1);

  console.log("removed marker "+mapItem.icon+":"+mapItem.nid+' '+mapItem.name);
};

我在控制台中添加了更多的调试信息,进入地图上只有2个标记的简单区域 http://www.trailforks.com/map/test.php?lat=49.43210641783767&lon=-123.49878636730955&z=14

我可以看到已经创建了标记,然后移动地图一点点,发现标记没有重新创建,因为它们在标记对象中被检测到了。然后我移动视口,使其中一个标记从屏幕上消失,我可以看到标记被删除,并且标记对象的长度更新了。但是如果我将地图平移回标记上,标记仍然在地图上。

enter image description here


1
我在尝试复现可能存在的“bug”时遇到了困难。我看过你的代码,写得很好,而且据我所见你做的事情是正确的。虽然这不重要,但在将其从数组中裁剪之前,你是否尝试将整个data[i]对象设置为null - dda
顺便说一句,对于一个写得好、聪明的问题,我会点赞的... - dda
我尝试添加“mapper.data[i] = null;”,但没有效果。 - Canadaka
我仍然没有弄清楚为什么会发生这种情况,或者另一种方法去解决它。 - Canadaka
2个回答

4
我曾经也遇到过类似的问题,长时间苦苦寻找原因,最终发现地图标记器的setMap方法是异步的。如果您调用此方法并立即删除与该标记对象相关的任何引用,则浏览器的垃圾回收程序会将其从内存中清除,从而防止实际的删除操作发生。

试试将splice调用的那一行注释掉,看看是否有所帮助。如果有帮助,您应该考虑延迟删除该对象,或者在真正删除之前存储对标记对象的引用。如何检测是否已经真正删除?我不知道。

希望这可以帮助您!


0

不要这样做:

 google.maps.event.addListener(map, 'dragend', function() {  refreshMarkers(); }); //refresh markers when user moves map
 google.maps.event.addListener(map, 'zoom_changed', function() {  refreshMarkers(); }); //refresh markers when user moves map

将其更改为:

编辑(评论后):

为了防止事件处理程序的多个实例同时发生,可以使用全局变量,如下所示:

google.maps.event.addListener(map, 'bounds_changed', function() {  
if (processing) { // var processing is global
    return;
}
processing = true;
refreshMarkers(); 
processing = false;

}); //refresh markers when user moves map

这应该涵盖了两种情况。现在有两个不同的事件监听器,AJAX调用可能会发生冲突,您可能会在第一个调用完成之前触发第二个调用。


使用"bounds_changed"的问题在于它会在鼠标的每一个微小移动时开始调用大量ajax调用,这可能会导致用户松开鼠标时产生数百个调用。但是我已经尝试过了,问题仍然存在,如果我在加载一些标记后平移,然后缩小地图视图,即使只有单个侦听器,也不会删除任何标记。我还测试了仅启用dragend或zoom_changed。 - Canadaka
这可以通过一个全局变量来轻松防止,该变量指示正在处理事件(请参见我的回复中的编辑)。 - Marcelo
以上代码仍然无法正常工作,它似乎从来没有变为真,并且我在Firebug控制台中得到了大量的POST中止。地图非常卡顿。只有一个监听器会很好,但我相当确定我的标记未删除的问题与具有多个监听器无关,因为即使启用一个监听器,我也可以产生该问题。 - Canadaka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接