如何在leaflet地图中更改默认光标?

28

当某个控制按钮被按下时,我想修改默认的光标图标。我在容器 div 上使用 css 部分地成功了,但这会覆盖移动光标状态,这不是我想要的。我的意思是,在移动地图时(但不是在标记上),移动图标不再出现。

我想知道是否有一种非 hacky 的方式通过 api 实现特殊的光标行为,而不需要重新定义所有内容。

这是我尝试做的事情,#map 是 leaflet 地图的容器 div。

#map[control=pressed] {
    cursor: url('..custom.png');
}

当控制按钮被禁用时,是否已向该按钮添加任何类? - Grace Huang
8个回答

54

编辑5.18.2017:通过Leaflet框架使用原始CSS和Javascript(推荐)

我正在查看BoxZoom插件的源代码,并注意到他们使用Leaflet内置的DOM mutators来实现,并想在此提倡它...这肯定是最佳实践。

示例 jsfiddle

在您的CSS中包含类似于以下内容的类。

.leaflet-container.crosshair-cursor-enabled {
    cursor:crosshair;
}

当你想启用十字准线时,请在你的JS中执行以下操作。

// Assumes your Leaflet map variable is 'map'..
L.DomUtil.addClass(map._container,'crosshair-cursor-enabled');

然后,当你想禁用十字准线时,在你的JS中执行以下操作。

L.DomUtil.removeClass(map._container,'crosshair-cursor-enabled');

翻译后的内容: 地图级别的十字线

@scud42把我引导到了正确的路径。您可以使用JQuery来更改Leaflet地图的光标,如下所示:

$('.leaflet-container').css('cursor','crosshair');

稍后,当您想要重置地图光标时,可以执行以下操作:

$('.leaflet-container').css('cursor','');

编辑于 2016年1月21日:针对每个要素的十字线

您还可以为支持className选项的单个要素启用十字线,例如多边形或要素顶点等。

以下是一个可拖动顶点的示例,将切换指针十字线 (jsfiddle):

var svg_html_default = '<div style="margin:0px;padding:0px;height:8px;width:8px;border-style:solid;border-color:#FFFFFF;border-width:1px;background-color:#424242"</div>';

var default_icon = L.divIcon({
  html: svg_html_default,
  className: 'leaflet-mouse-marker',
  iconAnchor: [5,5],
  iconSize: [8,8]
});

var m = new L.marker([33.9731003, -80.9968865], {
  icon: default_icon,
  draggable: true,
  opacity: 0.7
}).addTo( map );

m.on("mouseover",function(){$('.leaflet-mouse-marker').css('cursor','crosshair');});

m.on("mouseout",function(){$('.leaflet-mouse-marker').css('cursor','');});

虽然这对我来说已经过时了很久,但我将其作为正确答案授予。感谢 jsfiddle 让我能够证实工作行为。 - Marco Toniut

12

Leaflet的样式允许您更改一些光标行为。将它们放在您的本地CSS中以进行更改。

/* Change cursor when mousing over clickable layer */
.leaflet-clickable {
  cursor: crosshair !important;
}
/* Change cursor when over entire map */
.leaflet-container {
  cursor: help !important;
}

5

设置为十字准线:

document.getElementById('map').style.cursor = 'crosshair'

重置回原始状态:

document.getElementById('map').style.cursor = ''

2
使用active伪类。
#map:active {
    cursor: url('..custom.png');
}

JSFiddle

如果要覆盖光标,您可能需要使用css3属性user-select: none,这样在拖动元素时,它不会在文本和默认光标之间切换。该实现也在JSFiddle中显示。


我尝试按照您的建议操作,但似乎API正在破坏伪类行为。虽然在地图控件上它是有效的(这恰恰是我不想发生的事情)。 - Marco Toniut
你最终解决了这个问题吗? - jotamon
@snowgage,这个问题已经很久了,我甚至都不记得了。我相信在解决这个问题之前,我已经转向其他事情了。 虽然我很快就会回到映射场景,但如果这个问题再次出现并且我找到了答案,我一定会在这里发布的。 - Marco Toniut

1
这是对我有用的方法:

// CSS first. Add this to leaflet stylesheet.
.leaflet-interactive.wait-cursor-enabled {
    cursor: wait !important;
}

// JS select from map container and add class to each element
let map = L.map('map');
let els = map.getContainer().querySelectorAll('.leaflet-interactive');
for(let el of els){
   el.classList += ' wait-cursor-enabled'; 
}

//JS remove class once no longer needed
let els = map.getContainer().querySelectorAll('.leaflet-interactive.wait-cursor-enabled');
for(let el of els){
   el.classList.remove("wait-cursor-enabled");
}

1

我使用react-leaflet,需要根据应用程序中较高级别的状态更改地图和其上面的多边形的光标。更改地图本身的光标很简单:

map.getContainer().style.cursor = 'crosshair';

对于地图上的多边形,这并不是那么直接。Leaflet多边形采用className选项,可以用来覆盖默认的leaflet-interactive类,该类将光标设置为pointer。然而,我发现className不是一个动态选项:重新渲染多边形不会改变className(参见此 github 问题)。
我使用styled-components,所以尝试包装多边形组件以覆盖cursor样式规则,但是这也只在首次创建多边形时起作用。最终,我决定捕获对多边形对象的引用:
<Polygon ref={(el:any) => this.wrapperRef = el} /* ... */ />

并使用此方法在更新时设置光标样式规则:

componentDidUpdate = () => {
  this.wrapperRef._path.style.cursor = this.props.cursor;
}

如在 上述 Github 问题 中所讨论的那样,由 Leaflet 创建的对象的属性 _path 可用于访问和重写样式。


1
$('.leaflet-container').css('cursor','crosshair');

0
添加另一个选择器到你的规则中,它也将匹配 .leaflet-interactive 类。
#map[control=pressed],
#map[control=pressed] .leaflet-interactive {
    cursor: url('..custom.png');
}

根本问题在于基于svg的覆盖层,其中包含具有leaflet-interactive类的内部元素。
<svg> <g> <path class="leaflet-interactive">...

原来leaflet的本地样式 .leaflet-interactive { cursor: pointer; } 在svg内部具有更高的特异性,甚至比主文档中基于id的规则还要高。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接