如何在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
相关产品推荐
相关产品推荐

