Mapbox鼠标悬停弹窗无法关闭问题求助
解决Mapbox弹窗mouseleave无法关闭的问题
嗨,我一眼就揪出问题所在啦!你在mouseenter事件里创建的popup是局部变量,mouseleave的回调函数根本访问不到它,所以执行popup.remove()相当于在调用一个不存在的对象方法,自然没效果~
问题根源
你当前的代码中,popup变量被定义在mouseenter事件的回调函数内部,这个变量的作用域只限于该回调函数。当mouseleave事件触发时,它无法获取到这个局部的popup对象,打开浏览器控制台的话,应该能看到popup is not defined的报错提示。
修正方案
我们只需要把popup变量提升到两个事件回调都能访问的作用域里,同时在创建新弹窗前清理旧弹窗,避免重复叠加:
<html> <body> <div id='map'></div> <script> mapboxgl.accessToken = 'pk.eyJ1IjoibWFyeXNoYWZmZXIiLCJhIjoiY2poNnkwZ3pvMDI5ZzJ4cWUyY296NnNjdCJ9.PgJCuPhDYgm8oCmsZlAeQA'; // replace this with your access token var map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/maryshaffer/cjh6yf7c30apg2sotfzmyf2je', // replace this with your style URL }); map.addControl(new mapboxgl.NavigationControl()); // 把popup变量提升到全局作用域,让两个事件回调都能访问 let popup; map.on('mouseenter', 'pilgrimage-sites-markers', function(e) { // 改变光标样式,给用户视觉反馈 map.getCanvas().style.cursor = 'pointer'; var features = map.queryRenderedFeatures(e.point, { layers: ['pilgrimage-sites-markers'] // 替换成你的图层名称 }); if (!features.length) { return; } var feature = features[0]; // 如果已有弹窗,先移除旧的,避免叠加 if (popup) popup.remove(); popup = new mapboxgl.Popup({ closeOnClick: false, offset: [0, -15] }) .setLngLat(feature.geometry.coordinates) .setHTML('<h3>' + feature.properties.title + '</h3><p>' + feature.properties.description + '</p><h4><a href="' + feature.properties.link + '">Learn More</a></h4>') .addTo(map); }); map.on('mouseleave', 'pilgrimage-sites-markers', function() { map.getCanvas().style.cursor = ''; // 现在能访问到popup变量,存在的话就移除 if (popup) { popup.remove(); popup = null; // 清空变量,避免残留引用导致潜在问题 } }); </script> </body> </html>
额外优化说明
- 在
mouseenter里增加了旧弹窗判断,防止鼠标快速移动时创建多个弹窗叠加 mouseleave移除弹窗后把popup设为null,避免内存泄漏风险
这样修改后,鼠标离开marker图层时,弹窗就能正常关闭啦!
内容的提问来源于stack exchange,提问作者Mary Shaffer
相关产品推荐
相关产品推荐

