我试图在Leaflet中为CTRL +点击编写自定义事件处理程序。我的问题是地图给出的点击位置与事件处理程序中的点击位置不同,例如来自地图的LatLng(51.49174, -0.11639)
点击在处理程序中变为LatLng(51.50938, -0.126)
。如果地图是页面上唯一的内容,则点击位置会完全匹配。在地图上方添加一些其他div元素(如<h1>
标题)会使点击次数不匹配。平移地图也会使点击位置不匹配。
我想知道我是否正确地附上了L.DomEvent.on()
。在Leaflet Handlers tutorial之后,我的代码看起来像
L.CtrlClickHandler = L.Handler.extend({
addHooks: function() {
L.DomEvent.on(document, 'click', this._captureClick, this);
},
removeHooks: function() {
L.DomEvent.off(document, 'click', this._captureClick, this);
},
_captureClick: function(event) {
if (event.ctrlKey) {
console.log('control click registered at layer '
+ map.layerPointToLatLng(new L.point(event.layerX, event.layerY)));
}
}
});
// add this to all maps
L.Map.addInitHook('addHandler', 'ctrlClick', L.CtrlClickHandler);
由于我的代码中有一些其他依赖项,我使用的是Leaflet 0.7.7。升级到Leaflet 1.0.1使其更匹配(例如,LatLng(51.49868, -0.1018)
与LatLng(51.4987, -0.1018)
),但这两个位置仍然不完全相同。
我是否将L.DomEvent附加到正确的位置?应该以某种方式附加到地图div,而不是document
?
编辑:感谢@AlexParij的建议。我意识到平移地图也会使点击次数不匹配,无论是否有地图上方的div
元素。 Leaflet 1.0.1和0.7.7都会出现这种情况。我已经尝试了我能想到的每一个组合,结合了不同的事件位置(event.layerX
,event.pageX
,event.clientX
,event.offsetX
,event.screenX
和{ {1}})使用投影方法event.x
和layerPointToLatLng
,但它们都不匹配地图点击。现在我真的很困惑......摆弄这些不同的选项和Leaflet 1.0.1:https://jsfiddle.net/c4tkyewz/
答案 0 :(得分:1)
<强> TL; DR:在自定义处理程序中使用componentWillReceiveProps()
。
@AlexParij是对的;我没有使用层点和容器点的正确定义。在处理程序内部,map.mouseEventToLatLng()
与Leaflet的内部鼠标事件(位置可从event
获得)不同。
我查看了Leaflet的核心以找到答案。从e.latlng
获取位置需要参加鼠标事件 - &gt;容器点 - &gt;层点 - &gt;的latLng。值得庆幸的是,Leaflet开发人员已经为此编写了一个很好的函数:event
。
mouseEventToLatLng()
Leaflet 1.0.1的实例:https://jsfiddle.net/c4tkyewz/1/
还使用Leaflet 0.7.7进行测试。
<小时/> 作为奖励,要直接从Leaflet本机处理点击事件/*
* This is a custom handler to check if someone has control clicked
* the map and print the location of the click
*/
L.CtrlClickHandler = L.Handler.extend({
addHooks: function() {
L.DomEvent.on(document, 'click', this._captureClick, this);
},
removeHooks: function() {
L.DomEvent.off(document, 'click', this._captureClick, this);
},
_captureClick: function(event) {
if (event.ctrlKey) {
// translate mouse event to lat/lng (note: `mouseEventToLatLng()`
// calls Leaflet's `mouseEventToContainerPoint()` followed by
// `containerPointToLayerPoint()` and finally `layerPointToLatLng()`)
var latlng = map.mouseEventToLatLng(event);
console.log('Handler detected CTRL + click at ' + latlng);
}
}
});
// add this to all maps
L.Map.addInitHook('addHandler', 'ctrlClick', L.CtrlClickHandler);
访问CTRL键,请使用map.on('click', function(e) {});
。