You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Leaflet地图右键菜单添加滚动条后滚动时菜单消失问题求助

解决Leaflet右键菜单滚动时消失的问题

嘿,我帮你搞定这个滚动右键菜单就消失的问题!这个问题的核心是滚动事件冒泡到了地图上,触发了右键菜单的关闭逻辑,同时你的CSS设置也需要调整得更精准一些。下面是具体的解决方案:

步骤1:调整CSS,把滚动应用到菜单内容列表

原来的CSS把height和overflow直接加在了整个菜单容器上,这可能导致滚动事件被错误捕获。我们应该把滚动限制在菜单的选项列表里:

/* 让右键菜单的选项列表可滚动 */
.leaflet-contextmenu .leaflet-contextmenu-items {
  max-height: 120px; /* 根据你的需求设置最大高度 */
  overflow-y: auto;
  margin: 0; /* 移除默认边距,避免滚动条错位 */
  padding: 4px 0;
}

/* 可选:美化滚动条样式 */
.leaflet-contextmenu .leaflet-contextmenu-items::-webkit-scrollbar {
  width: 6px;
}
.leaflet-contextmenu .leaflet-contextmenu-items::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}
.leaflet-contextmenu .leaflet-contextmenu-items::-webkit-scrollbar-thumb {
  background: #888;
  border-radius: 3px;
}
.leaflet-contextmenu .leaflet-contextmenu-items::-webkit-scrollbar-thumb:hover {
  background: #555;
}

步骤2:阻止滚动事件冒泡,避免菜单关闭

Leaflet的右键菜单插件默认会在地图上的交互(包括滚动)触发时关闭菜单,我们需要在菜单的滚动事件上阻止事件冒泡,让菜单自己处理滚动:

var map, cm, ll = new L.LatLng(-36.852668, 174.762675), ll2 = new L.LatLng(-36.86, 174.77);
map = L.map('map', {
 center: ll,
 zoom: 15,
 contextmenu: true,
 contextmenuWidth: 140,
 contextmenuItems: [
 { text: 'Show coordinates' },
 { text: 'Center map here' },
 '-',
 { text: 'Zoom in' },
 { text: 'Zoom out' },
 { text: 'A' },
 { text: 'B' },
 { text: 'C' },
 { text: 'D' },
 { text: 'E' },
 { text: 'F' }
 ]
});

// 添加这部分代码:阻止菜单滚动时的事件冒泡
map.on('contextmenu.show', function(e) {
  const menuItems = e.contextmenu._container.querySelector('.leaflet-contextmenu-items');
  if (menuItems) {
    menuItems.addEventListener('wheel', function(event) {
      event.stopPropagation(); // 不让滚动事件传到地图上
    }, { passive: false });
  }
});

L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
 attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
L.marker(ll, {
 contextmenu: true,
 contextmenuItems: [{ text: 'Marker item', index: 0 }, { separator: true, index: 1 }]
}).addTo(map);
L.marker(ll2, {
 contextmenu: true,
 contextmenuInheritItems: false,
 contextmenuItems: [{ text: 'Marker item' }]
}).addTo(map);

步骤3:完整的HTML代码

把调整后的CSS和JS整合到HTML里:

<!doctype html>
<html>
<head>
 <title>Leaflet Context Menu</title>
 <link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.2/dist/leaflet.css"/>
 <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/aratcliffe/Leaflet.contextmenu/dist/leaflet.contextmenu.min.css"/>
 <style>
 /* 让右键菜单的选项列表可滚动 */
 .leaflet-contextmenu .leaflet-contextmenu-items {
   max-height: 120px;
   overflow-y: auto;
   margin: 0;
   padding: 4px 0;
 }

 /* 可选:美化滚动条 */
 .leaflet-contextmenu .leaflet-contextmenu-items::-webkit-scrollbar {
   width: 6px;
 }
 .leaflet-contextmenu .leaflet-contextmenu-items::-webkit-scrollbar-track {
   background: #f1f1f1;
   border-radius: 3px;
 }
 .leaflet-contextmenu .leaflet-contextmenu-items::-webkit-scrollbar-thumb {
   background: #888;
   border-radius: 3px;
 }
 </style>
</head>
<body>
 <div id="map" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></div>
 <script src="https://unpkg.com/leaflet@1.0.2/dist/leaflet.js"></script>
 <script src="https://cdn.jsdelivr.net/gh/aratcliffe/Leaflet.contextmenu/dist/leaflet.contextmenu.min.js"></script>
 <script>
 var map, cm, ll = new L.LatLng(-36.852668, 174.762675), ll2 = new L.LatLng(-36.86, 174.77);
 map = L.map('map', {
  center: ll,
  zoom: 15,
  contextmenu: true,
  contextmenuWidth: 140,
  contextmenuItems: [
  { text: 'Show coordinates' },
  { text: 'Center map here' },
  '-',
  { text: 'Zoom in' },
  { text: 'Zoom out' },
  { text: 'A' },
  { text: 'B' },
  { text: 'C' },
  { text: 'D' },
  { text: 'E' },
  { text: 'F' }
  ]
 });

 // 阻止菜单滚动时关闭
 map.on('contextmenu.show', function(e) {
   const menuItems = e.contextmenu._container.querySelector('.leaflet-contextmenu-items');
   if (menuItems) {
     menuItems.addEventListener('wheel', function(event) {
       event.stopPropagation();
     }, { passive: false });
   }
 });

 L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
  attribution: '&amp;copy; &lt;a href="http://osm.org/copyright"&gt;OpenStreetMap&lt;/a&gt; contributors'
 }).addTo(map);
 L.marker(ll, {
  contextmenu: true,
  contextmenuItems: [{ text: 'Marker item', index: 0 }, { separator: true, index: 1 }]
 }).addTo(map);
 L.marker(ll2, {
  contextmenu: true,
  contextmenuInheritItems: false,
  contextmenuItems: [{ text: 'Marker item' }]
 }).addTo(map);
 </script>
</body>
</html>

这样修改后,右键菜单的滚动条就能正常工作,滚动时菜单也不会消失了!原理是:

  1. 把滚动区域限制在菜单的选项列表内,确保滚动事件被菜单元素捕获
  2. 阻止滚动事件冒泡到地图,避免触发菜单的关闭逻辑

内容的提问来源于stack exchange,提问作者Mahbub

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 09:42:36