Leaflet封装Map类点击地图新增标记时移除旧标记方法
Leaflet封装Class后点击地图多标记生成问题修复
问题根因
- 自定义封装
Map类实现地图功能时,要求地图始终仅展示1个标记:初始化时在中心生成初始标记,用户点击地图时删除旧标记、在点击位置生成新标记 - 实际运行点击会重复生成多个标记,手动加移除逻辑时抛出
ReferenceError: marker is not defined错误 - 报错本质是Class的方法作用域隔离:初始标记、点击生成的新标记分别在两个独立方法内以局部变量声明,跨方法无法访问;之前非Class写法依赖的全局
let marker变量,在Class封装场景下不再适用
修复方案
将标记实例挂载为Class的实例属性,所有方法通过this即可共享访问该实例,无需依赖全局变量。
代码实现
- 初始化Class时提前声明存储标记的实例属性,默认值设为
nullclass Map { constructor(container, options) { // 原有地图实例初始化逻辑 this.map = L.map(container, options); // 新增:存储当前展示的标记实例 this.activeMarker = null; } - 初始中心标记创建完成后,将实例赋值给该实例属性
// 原有生成初始中心标记的marker方法 marker() { const center = this.map.getCenter(); this.activeMarker = L.marker(center).addTo(this.map); } - 点击事件触发的新标记生成逻辑中,先判断存在旧标记就移除,再生成新标记更新实例属性
// 原有点击生成新标记的newMarker方法 newMarker(latlng) { // 移除已存在的旧标记 if (this.activeMarker) { this.map.removeLayer(this.activeMarker); } // 生成新标记并更新实例存储 this.activeMarker = L.marker(latlng).addTo(this.map); } - 初始化流程绑定事件,注意修正
this指向避免访问实例属性失败init() { // 原有底图加载等逻辑 // 生成初始标记 this.marker(); // 绑定地图点击事件,用箭头函数保证this指向Class实例 this.map.on('click', (e) => { this.newMarker(e.latlng); }); } }
避坑提示:如果绑定事件不用箭头函数,需要手动给回调函数绑定
.bind(this),否则回调内的this会指向地图实例而非自定义Map类的实例,导致无法读取activeMarker属性。
内容的提问来源于stack exchange,提问作者Jack The Baker
相关产品推荐
相关产品推荐

