Leaflet map locationfound 触发意外的监听器
Leaflet map locationfound triggers unintended listener
我有一张传单地图,其中 map.locate()
可以通过两种方式调用:1. Easybutton 定位按钮,2. 使用 setTimeout 每分钟定期调用。
每个人都有自己的 locationfound
侦听器,或者至少我希望他们有 - 这就是问题所在:单击 easybutton 会同时触发 control._map.on('locationfound'..)
easybutton 侦听器和 map.on('locationfound'..)
getLocation() 中的侦听器。
对 getLocation() 的常规调用只会触发 map.on('locationfound'..)
侦听器。
这与范围有关吗?
我如何获得它,以便 easybutton 仅触发其预期的侦听器,而对 map.locate() 的 setTimeout 调用仅触发 getLocation() 中的侦听器?
L.easyButton({
position: easy_position,
states:[
{
stateName: 'unloaded',
icon: 'fa-location-arrow',
title: 'load image',
onClick: function(control){
control.state("loading");
control._map.on('locationfound', function(e){
alert('location found - easybutton');
this.setView(e.latlng,18); // go to current location
control.state('loaded');
setTimeout(function(){
control.state('unloaded');
}, 3000);
});
control._map.on('locationerror', function(){
control.state('error');
setTimeout(function(){
control.state('unloaded');
}, 3000);
});
control._map.locate();
setTimeout(function(){
control.state('unloaded');
}, 10000); // give it ten seconds to find the location
}
}, {
stateName: 'loading',
icon: 'fa-spinner fa-spin'
}, {
stateName: 'loaded',
icon: 'fa-thumbs-up'
}, {
stateName: 'error',
icon: 'fa-frown-o',
title: 'location not found'
}
]
}).addTo(map);
function updateLocation() {
getLocation(false);
setTimeout(updateLocation, 60000);
}
getLocation = function(goToLocation) {
map.on('locationfound', function(e) {
alert('location found - getLocation()');
var lat = e.latitude;
var lng = e.longitude;
if(goToLocation) {
pan_to(lat,lng,0.5);
}
});
map.on('locationerror', function(e) {
console.log(e);
});
map.locate({
setView: false,
maxZoom: 16
});
}
您可以通过使用 map.once()
method 附加您的事件侦听器(在您的常规流程和您的按钮中)来缓解您的问题,以便它们在触发一次后被删除:
Behaves as on(…)
, except the listener will only get fired once and then removed.
仍然存在一些可以同时触发两个侦听器的瞬态情况:如果您的按钮被点击,而您的常规进程已经启动了一个位置,但结果仍然未决,或者相反。
不幸的是,Leaflet 不区分对 map.locate()
方法的调用。因此@IvanSanchez 建议直接使用浏览器 API.
您可以通过在启动一个位置时管理标志/互斥量来消除这些瞬态情况,并且不执行另一个或延迟它,以防您的互斥量被锁定。
我有一张传单地图,其中 map.locate()
可以通过两种方式调用:1. Easybutton 定位按钮,2. 使用 setTimeout 每分钟定期调用。
每个人都有自己的 locationfound
侦听器,或者至少我希望他们有 - 这就是问题所在:单击 easybutton 会同时触发 control._map.on('locationfound'..)
easybutton 侦听器和 map.on('locationfound'..)
getLocation() 中的侦听器。
对 getLocation() 的常规调用只会触发 map.on('locationfound'..)
侦听器。
这与范围有关吗?
我如何获得它,以便 easybutton 仅触发其预期的侦听器,而对 map.locate() 的 setTimeout 调用仅触发 getLocation() 中的侦听器?
L.easyButton({
position: easy_position,
states:[
{
stateName: 'unloaded',
icon: 'fa-location-arrow',
title: 'load image',
onClick: function(control){
control.state("loading");
control._map.on('locationfound', function(e){
alert('location found - easybutton');
this.setView(e.latlng,18); // go to current location
control.state('loaded');
setTimeout(function(){
control.state('unloaded');
}, 3000);
});
control._map.on('locationerror', function(){
control.state('error');
setTimeout(function(){
control.state('unloaded');
}, 3000);
});
control._map.locate();
setTimeout(function(){
control.state('unloaded');
}, 10000); // give it ten seconds to find the location
}
}, {
stateName: 'loading',
icon: 'fa-spinner fa-spin'
}, {
stateName: 'loaded',
icon: 'fa-thumbs-up'
}, {
stateName: 'error',
icon: 'fa-frown-o',
title: 'location not found'
}
]
}).addTo(map);
function updateLocation() {
getLocation(false);
setTimeout(updateLocation, 60000);
}
getLocation = function(goToLocation) {
map.on('locationfound', function(e) {
alert('location found - getLocation()');
var lat = e.latitude;
var lng = e.longitude;
if(goToLocation) {
pan_to(lat,lng,0.5);
}
});
map.on('locationerror', function(e) {
console.log(e);
});
map.locate({
setView: false,
maxZoom: 16
});
}
您可以通过使用 map.once()
method 附加您的事件侦听器(在您的常规流程和您的按钮中)来缓解您的问题,以便它们在触发一次后被删除:
Behaves as
on(…)
, except the listener will only get fired once and then removed.
仍然存在一些可以同时触发两个侦听器的瞬态情况:如果您的按钮被点击,而您的常规进程已经启动了一个位置,但结果仍然未决,或者相反。
不幸的是,Leaflet 不区分对 map.locate()
方法的调用。因此@IvanSanchez 建议直接使用浏览器 API.
您可以通过在启动一个位置时管理标志/互斥量来消除这些瞬态情况,并且不执行另一个或延迟它,以防您的互斥量被锁定。