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

如何在Leaflet.js中实现input radio与input checkbox联动的地图标记筛选

Leaflet.js 门店多维度筛选功能实现方案

核心思路是给所有地图标记挂载自定义属性做维度标识,统一维护标记列表,每次筛选触发时遍历标记做匹配判断,控制标记在地图上的显隐即可。


步骤1:预处理标记数据

初始化标记时给每个标记挂载门店类型、所属企业两个自定义属性,同时把所有标记存入统一的全局数组方便后续遍历操作。

// 示例门店结构化数据,可根据实际业务替换
const storeList = [
  {type: 'grocery', company: '永辉超市', lat: 30.234, lng: 120.567, name: '永辉西湖店'},
  {type: 'clothing', company: '优衣库', lat: 30.235, lng: 120.568, name: '优衣库银泰店'},
  {type: 'pharmacy', company: '益丰大药房', lat: 30.236, lng: 120.569, name: '益丰文二路店'},
  // 其余门店数据...
]
const allMarkers = []
// 初始化地图实例(假设你已经初始化了地图容器为map)
const map = L.map('map-container').setView([30.234, 120.567], 13)
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map)

// 批量生成标记
storeList.forEach(item => {
  const marker = L.marker([item.lat, item.lng]).bindPopup(`<b>${item.name}</b><br>${item.company}`)
  // 挂载自定义筛选属性
  marker.storeType = item.type
  marker.company = item.company
  allMarkers.push(marker)
})

步骤2:编写筛选控件HTML

<!-- 门店类型单选控件 -->
<div class="filter-panel">
  <h4>门店类型</h4>
  <label><input type="radio" name="storeType" value="grocery" checked> 杂货店</label>
  <label><input type="radio" name="storeType" value="clothing"> 服装店</label>
  <label><input type="radio" name="storeType" value="pharmacy"> 药店</label>

  <h4>所属企业</h4>
  <label><input type="checkbox" name="company" value="永辉超市" checked> 永辉超市</label>
  <label><input type="checkbox" name="company" value="优衣库" checked> 优衣库</label>
  <label><input type="checkbox" name="company" value="益丰大药房" checked> 益丰大药房</label>
  <!-- 其余企业选项可从门店数据中去重提取动态生成,无需写死 -->
</div>

步骤3:实现筛选逻辑

写统一的筛选函数,所有筛选控件变动时都触发该函数,统一判断所有标记的显隐状态。

// 核心筛选函数
function updateMarkerDisplay() {
  // 1. 获取当前选中的门店类型
  const activeType = document.querySelector('input[name="storeType"]:checked').value
  // 2. 获取当前选中的企业列表
  const activeCompanies = Array.from(document.querySelectorAll('input[name="company"]:checked')).map(el => el.value)

  // 3. 遍历所有标记做匹配判断
  allMarkers.forEach(marker => {
    // 先移除标记,符合条件再重新添加到地图
    map.removeLayer(marker)
    // 同时匹配门店类型和所属企业才展示
    if (marker.storeType === activeType && activeCompanies.includes(marker.company)) {
      marker.addTo(map)
    }
  })
}

// 给所有筛选控件绑定变更事件
document.querySelectorAll('input[name="storeType"], input[name="company"]').forEach(input => {
  input.addEventListener('change', updateMarkerDisplay)
})

// 页面加载完成后初始化展示默认筛选结果
updateMarkerDisplay()

可选优化点

  • 如果标记数量超过1000个,可给每个标记增加isActive状态标记,仅当状态发生变化时才执行addLayer/removeLayer操作,减少DOM操作提升性能
  • 如果需要切换门店类型时动态更新可选企业列表(比如选服装店时仅展示有服装店的企业选项),可在updateMarkerDisplay函数中新增逻辑:提取当前类型下所有门店的所属企业,去重后重写企业复选框的DOM结构即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 19:45:00