项目中有这样一个需求:点击地图添加标记点和label提示框,点击提示框中的按钮可以触发一个点击事件 (如图一),并可在地图上重新选点标记。(上个点会被清除)
在这个过程中遇到了一个问题是点击label会穿透到地图上改变当前标记点的位置。期间尝试过阻止冒泡这种方法,虽然有效果,但是关掉‘’创建摆摊‘’点击事件触发的弹框后,重新选点会发生需要点击两次地图才能重新添加标记的bug。
图一:
解决方案
找了好久的办法,发现可以这样解决。不需要阻止冒泡,只需要在地图监听事件中加上一个判断,代码如下:
//地址解析
let geocoder = new BMap.Geocoder();
//添加点击事件监听
map.addEventListener('click', function(e) {
//如果是地图点击事件就进行以下操作(就是if这一行的判断)
if (e.overlay == null) {
console.log('触发地图点击');
let allOverlay = that.map.getOverlays();
//清除上次点圈
for (let i = 0; i < allOverlay.length - 1; i++) {
if (
allOverlay[i].toString() == '[object Marker]' ||
allOverlay[i].toString() == '[object Circle]'
) {
that.map.removeOverlay(allOverlay[i]);
}
}
//获取点所在街道地址
geocoder.getLocation(e.point, function(rs) {
let addComp = rs.addressComponents;
that.form.address =
addComp.province +
addComp.city +
addComp.district +
addComp.street +
addComp.streetNumber;
that.form.addrPoint.lat = e.point.lat;
that.form.addrPoint.lng = e.point.lng;
let label = new BMap.Label(
`<div style="font-weight:bold">当前选中位置:</div><div>${
that.form.address
}</div><button οnclick="createActive()" style="cursor:point;margin-top:4px">创建摆摊</button>`,
{ offset: new BMap.Size(20, -70) },
);
label.setStyle({
color: '#000',
padding: '10px',
fontFamily: '微软雅黑',
border: 'none',
borderRadius: '4px',
background: '#fff',
boxShadow: '0 0 5px #333',
});
marker.setLabel(label);
});
let point = new BMap.Point(e.point.lng, e.point.lat);
//绘制点
let marker = new BMap.Marker(point);
that.a = marker;
map.addOverlay(marker);
//绘制圈
let circle = new BMap.Circle(
new BMap.Point(e.point.lng, e.point.lat),
that.value,
{
strokeColor: 'red',
strokeWeight: 2,
strokeOpacity: 0.5,
},
);
map.addOverlay(circle);
window.createActive = function() {
that.dialogVisible = true;
};
}
});
添加这一行之后,再点击label就不会触发地图的点击事件了。这句话的意思是如果你点击的不是地图中的覆盖物就会执行if中的代码。