Leaflet:在 For 循环中创建单独的事件监听器
Leaflet: create individual Event-listeners inside For-loops
我想在地图上放几个标记,这些标记由"parent"个标记和"child"个标记组成。所有父标记应同时在地图上可见,而如果单击特定父标记
,则应切换特定父标记的子标记on/off
我创建了以下工作示例来演示:
<!DOCTYPE html>
<html>
<head>
<title>Test 1</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.0.1/dist/leaflet.js"></script>
<style>
body {padding: 0; margin: 0;}
html, body, #map {height: 100%;}
</style>
</head>
<body>
<div id='map'></div>
<script>
var thunder = L.tileLayer('https://{s}.tile.thunderforest.com/neighbourhood/{z}/{x}/{y}.png', {subdomains:'abc', attribution:'<a href="http://www.thunderforest.com">Thunderforest</a> | <a href="http://www.openstreetmap.org/copyright/">OpenStreetMap</a>' });
var map = L.map('map',{layers: [thunder]}).setView([50.08, 10.08], 12);
var parent1 = L.marker([50.0, 10.0]).bindPopup('Marker 1');
var parent2 = L.marker([50.1, 10.1]).bindPopup('Marker 2');;
var layergroupParents = L.layerGroup([parent1, parent2]);
layergroupParents.addTo(map);
var child1a = L.marker([50.02, 10.02],{title: 'Child 1a'});
var child1b = L.marker([50.04, 10.04],{title: 'Child 1b'});
var layergroupChilds1 = L.layerGroup([child1a, child1b]);
var child2a = L.marker([50.12, 10.12],{title: 'Child 2a'});
var child2b = L.marker([50.14, 10.14],{title: 'Child 2b'});
var layergroupChilds2 = L.layerGroup([child2a, child2b]);
parent1.on('click', function(){
if (map.hasLayer(layergroupChilds1)) {
map.removeLayer(layergroupChilds1)
} else {
layergroupChilds1.addTo(map);
}
});
parent2.on('click', function(){
if (map.hasLayer(layergroupChilds2)) {
map.removeLayer(layergroupChilds2)
} else {
layergroupChilds2.addTo(map);
}
});
</script>
</body>
</html>
因为我要显示比较多的标记,所以我想把标记的属性放到一个数组中("markerArray"),然后通过For-Loops处理它的标记:
<!DOCTYPE html>
<html>
<head>
<title>Test 2</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.0.1/dist/leaflet.js"></script>
<style>
body {padding: 0; margin: 0;}
html, body, #map {height: 100%;}
</style>
</head>
<body>
<div id='map'></div>
<script>
var thunder = L.tileLayer('https://{s}.tile.thunderforest.com/neighbourhood/{z}/{x}/{y}.png', {subdomains:'abc', attribution:'<a href="http://www.thunderforest.com">Thunderforest</a> | <a href="http://www.openstreetmap.org/copyright/">OpenStreetMap</a>' });
var map = L.map('map',{layers: [thunder]}).setView([50.08, 10.08], 12);
var markerArray = [
["Marker 1", 50.0, 10.0, [["Child 1a", 50.02, 10.02], ["Child 1b", 50.04, 10.04]]],
["Marker 2", 50.1, 10.1, [["Child 1a", 50.12, 10.12], ["Child 1b", 50.14, 10.14]]],
];
var numberParents = markerArray.length;
var layergroupParents = L.layerGroup();
for (cnt1=0; cnt1<numberParents; cnt1++) {
var parentObject = L.marker([markerArray[cnt1][1], markerArray[cnt1][2]]);
parentObject.bindPopup(markerArray[cnt1][0]);
layergroupParents.addLayer (parentObject);
var numberChilds = markerArray[cnt1][3].length;
var layergroupChilds = L.layerGroup();
for (cnt2=0; cnt2<numberChilds; cnt2++) {
var childObject = L.marker([markerArray[cnt1][3][cnt2][1], markerArray[cnt1][3][cnt2][2]], {title: markerArray[cnt1][3][cnt2][0]});
layergroupChilds.addLayer (childObject);
}
parentObject.on('click', function(){
if (map.hasLayer(layergroupChilds)) {
map.removeLayer(layergroupChilds)
} else {
layergroupChilds.addTo(map);
}
});
}
layergroupParents.addTo(map);
</script>
</body>
</html>
如果您执行这些脚本,您会发现,将一个单独的 'click' 事件分配给每个单独的父标记存在一些问题。现在只有 最后一个父标记 的子标记被切换 on/off 即使我点击第一个父标记。
您知道我如何解决这些问题并且脚本 2 的工作方式与脚本 1 中的一样吗?
要使其正常工作,您必须将子项附加到父项(使用 javascript 属性)
var layergroupChilds = L.layerGroup();
parentObject.layergroupChilds = layergroupChilds;
当父对象收到点击时,您可以在事件 e 中找到父对象,从而找到它的子对象。
parentObject.on('click', function(e){
if (map.hasLayer(e.target.layergroupChilds)) {
map.removeLayer(e.target.layergroupChilds)
} else {
e.target.layergroupChilds.addTo(map);
}
});
这是您的code 更正
我想在地图上放几个标记,这些标记由"parent"个标记和"child"个标记组成。所有父标记应同时在地图上可见,而如果单击特定父标记
,则应切换特定父标记的子标记on/off我创建了以下工作示例来演示:
<!DOCTYPE html>
<html>
<head>
<title>Test 1</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.0.1/dist/leaflet.js"></script>
<style>
body {padding: 0; margin: 0;}
html, body, #map {height: 100%;}
</style>
</head>
<body>
<div id='map'></div>
<script>
var thunder = L.tileLayer('https://{s}.tile.thunderforest.com/neighbourhood/{z}/{x}/{y}.png', {subdomains:'abc', attribution:'<a href="http://www.thunderforest.com">Thunderforest</a> | <a href="http://www.openstreetmap.org/copyright/">OpenStreetMap</a>' });
var map = L.map('map',{layers: [thunder]}).setView([50.08, 10.08], 12);
var parent1 = L.marker([50.0, 10.0]).bindPopup('Marker 1');
var parent2 = L.marker([50.1, 10.1]).bindPopup('Marker 2');;
var layergroupParents = L.layerGroup([parent1, parent2]);
layergroupParents.addTo(map);
var child1a = L.marker([50.02, 10.02],{title: 'Child 1a'});
var child1b = L.marker([50.04, 10.04],{title: 'Child 1b'});
var layergroupChilds1 = L.layerGroup([child1a, child1b]);
var child2a = L.marker([50.12, 10.12],{title: 'Child 2a'});
var child2b = L.marker([50.14, 10.14],{title: 'Child 2b'});
var layergroupChilds2 = L.layerGroup([child2a, child2b]);
parent1.on('click', function(){
if (map.hasLayer(layergroupChilds1)) {
map.removeLayer(layergroupChilds1)
} else {
layergroupChilds1.addTo(map);
}
});
parent2.on('click', function(){
if (map.hasLayer(layergroupChilds2)) {
map.removeLayer(layergroupChilds2)
} else {
layergroupChilds2.addTo(map);
}
});
</script>
</body>
</html>
因为我要显示比较多的标记,所以我想把标记的属性放到一个数组中("markerArray"),然后通过For-Loops处理它的标记:
<!DOCTYPE html>
<html>
<head>
<title>Test 2</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.0.1/dist/leaflet.js"></script>
<style>
body {padding: 0; margin: 0;}
html, body, #map {height: 100%;}
</style>
</head>
<body>
<div id='map'></div>
<script>
var thunder = L.tileLayer('https://{s}.tile.thunderforest.com/neighbourhood/{z}/{x}/{y}.png', {subdomains:'abc', attribution:'<a href="http://www.thunderforest.com">Thunderforest</a> | <a href="http://www.openstreetmap.org/copyright/">OpenStreetMap</a>' });
var map = L.map('map',{layers: [thunder]}).setView([50.08, 10.08], 12);
var markerArray = [
["Marker 1", 50.0, 10.0, [["Child 1a", 50.02, 10.02], ["Child 1b", 50.04, 10.04]]],
["Marker 2", 50.1, 10.1, [["Child 1a", 50.12, 10.12], ["Child 1b", 50.14, 10.14]]],
];
var numberParents = markerArray.length;
var layergroupParents = L.layerGroup();
for (cnt1=0; cnt1<numberParents; cnt1++) {
var parentObject = L.marker([markerArray[cnt1][1], markerArray[cnt1][2]]);
parentObject.bindPopup(markerArray[cnt1][0]);
layergroupParents.addLayer (parentObject);
var numberChilds = markerArray[cnt1][3].length;
var layergroupChilds = L.layerGroup();
for (cnt2=0; cnt2<numberChilds; cnt2++) {
var childObject = L.marker([markerArray[cnt1][3][cnt2][1], markerArray[cnt1][3][cnt2][2]], {title: markerArray[cnt1][3][cnt2][0]});
layergroupChilds.addLayer (childObject);
}
parentObject.on('click', function(){
if (map.hasLayer(layergroupChilds)) {
map.removeLayer(layergroupChilds)
} else {
layergroupChilds.addTo(map);
}
});
}
layergroupParents.addTo(map);
</script>
</body>
</html>
如果您执行这些脚本,您会发现,将一个单独的 'click' 事件分配给每个单独的父标记存在一些问题。现在只有 最后一个父标记 的子标记被切换 on/off 即使我点击第一个父标记。
您知道我如何解决这些问题并且脚本 2 的工作方式与脚本 1 中的一样吗?
要使其正常工作,您必须将子项附加到父项(使用 javascript 属性)
var layergroupChilds = L.layerGroup();
parentObject.layergroupChilds = layergroupChilds;
当父对象收到点击时,您可以在事件 e 中找到父对象,从而找到它的子对象。
parentObject.on('click', function(e){
if (map.hasLayer(e.target.layergroupChilds)) {
map.removeLayer(e.target.layergroupChilds)
} else {
e.target.layergroupChilds.addTo(map);
}
});
这是您的code 更正