Google Maps结合markerclustererplus时map_changed回调多次触发问题咨询
问题原因
你给所有标记都绑定了map_changed监听器,当地图缩放触发聚类时,所有被聚合的标记都会触发该事件,每个监听器判断到当前选中标记在聚类中时都会调用closeMarker(),因此出现多次执行的问题。
解决方案1:仅为当前选中标记绑定监听器(推荐)
修改步骤:
- 新增全局变量存储当前监听器句柄
var curMapChangedListener = null;
- 删除原来循环中给所有标记绑定
map_changed的通用代码,将绑定逻辑移到标记的点击事件中,每次点击新标记时先移除旧监听器,再给当前选中标记绑定新监听器
修改后的点击事件代码:
google.maps.event.addListener(marker, 'click', (function(marker, content, infowindow) { return function() { // 移除之前选中标记的监听器 if (curMapChangedListener) { google.maps.event.removeListener(curMapChangedListener); curMapChangedListener = null; } curMark = this; // 仅给当前选中标记绑定map_changed监听器 curMapChangedListener = google.maps.event.addListener(curMark, 'map_changed', function() { var clusters = markerClusterer.getClusters(); for (let i = 0, l = clusters.length; i < l; i++) { const markers = clusters[i].getMarkers(); if (markers.includes(curMark) && markers.length > 1) { try { if (infowindow !== null) { infowindow.close(); infowindow = null; } if (prev_infowindow) { prev_infowindow.close(); } closeMarker(); // 执行完即移除监听器 google.maps.event.removeListener(curMapChangedListener); curMapChangedListener = null; } catch (ee) {} break; } } }); // 原有InfoWindow逻辑不变 if (prev_infowindow) { prev_infowindow.close(); } prev_infowindow = infowindow; infowindow.setContent(content); infowindow.setOptions({ pixelOffset: new google.maps.Size(0, -42) }) infowindow.setPosition(marker.getPosition()) infowindow.open(map); }; })(marker, content, infowindow));
解决方案2:添加执行锁(快速修复)
如果不想修改绑定逻辑,新增全局执行锁即可避免多次调用:
- 新增全局锁变量
var closeMarkerLock = false;
- 在标记的点击事件中打开InfoWindow前重置锁:
// 放在点击事件中打开InfoWindow的逻辑前 closeMarkerLock = false;
- 修改
map_changed回调中调用closeMarker()的逻辑:
if (!closeMarkerLock) { closeMarkerLock = true; closeMarker(); }
内容的提问来源于stack exchange,提问作者satyrFrost
相关产品推荐
相关产品推荐

