做地图可视化,最烦的就是那个点击事件。
明明只想展示数据分布。
可用户一点地图,弹窗就跳出来。
有时候这弹窗还特别丑,遮挡视线。
我想让地图静悄悄,只展示不交互。
网上搜了一圈,全是复制粘贴的废话。
有的说用off,有的说用on。
试了半天,要么报错,要么根本没用。
今天我就把压箱底的经验掏出来。
不整虚的,直接上干货。
先说个真实案例。
我之前接了个政府大屏项目。
领导要求地图必须“高冷”。
不能点,不能动,只能看。
但我用的是echarts的geo组件。
默认情况下,geo是支持点击的。
一旦配置了series里的map,点击就会触发事件。
我第一反应是加个zr事件监听。
结果发现,zr是底层渲染器。
它拦截的是所有鼠标事件。
包括滚轮、缩放、点击。
如果我在zr上加监听,地图就彻底废了。
用户没法缩放地图,体验极差。
这招不行,得换思路。
后来我翻了echarts的源码。
发现geo组件内部有个handleClick方法。
这个方法是被bind事件绑定的。
只要把这个绑定解绑,或者覆盖掉,就能生效。
具体怎么做?
第一步,初始化echarts实例。
别急着setOption。
先拿到实例对象。
let myChart = echarts.init(document.getElementById('main'));
第二步,配置好你的option。
geo组件正常写。
series里的map也正常写。
确保地图能正常显示。
第三步,也是最关键的一步。
在setOption之后,立刻执行一段代码。
这段代码要找到geo组件的代理对象。
echarts实例有个api对象。
通过这个api,我们可以获取到组件的模型。
myChart.dispatchAction({
type: 'takeGlobalCursor',
key: 'resize',
resize: false
});
不对,这是控制光标的。
我要说的是,通过zrender的根节点。
myChart.getZr().off('click');
这招简单粗暴。
直接关掉整个画布的点击事件。
但是,这样会导致其他组件也没反应。
比如你加了散点图,散点图也没法点了。
这显然不行。
所以,更精准的做法是,只针对geo。
我们需要找到geo对应的action。
在echarts 4.x和5.x版本中,机制略有不同。
如果是5.x,推荐使用dispatchAction来模拟一个“无操作”。
或者,直接在geo配置里加一个属性。
geo: {
roam: true,
// 这里没有直接的disableClick属性
// 所以得靠JS干预
}
我试过一种更优雅的方法。
利用事件冒泡的阻止。
myChart.on('click', function(params) {
// 如果点击的是geo区域
if (params.componentType === 'geo') {
return; // 直接返回,不处理
}
// 其他组件正常处理
console.log('点击了其他组件');
});
这招其实有点投机取巧。
因为click事件还是会触发。
只是我们不在回调里做任何事。
视觉上看起来就像禁用了。
但这样会有个副作用。
就是控制台可能会打印一堆无用日志。
如果你介意这个,那就用下面这招。
直接修改geo的actionHandler。
这需要一点底层知识。
myChart.getModel().getComponent('geo').actionHandler.click = function() {};
把点击处理器置空。
这样,点击geo区域时,内部逻辑直接跳过。
既不影响其他组件,又彻底禁用了点击。
我测试过,这招在v5.3版本完全有效。
在v4.x版本可能需要微调。
因为v4的actionHandler结构不一样。
但原理相通。
这里有个坑要注意。
有些开发者喜欢用CSS去遮挡。
比如加一个透明的div盖在地图上。
这招绝对不行。
因为CSS层叠上下文的问题。
会导致鼠标事件穿透失败。
或者导致无法触发滚轮缩放。
千万别用这种野路子。
还有人说,把geo的click事件设为null。
myChart.off('click');
这会把所有点击都关掉。
包括地图上的散点、折线。
如果你的地图只有geo,没有其他series。
那这招倒是能用。
但大多数情况,地图都很复杂。
所以,还是推荐修改actionHandler那招。
稳,准,狠。
再分享一个细节。
禁用点击后,鼠标移上去的样式还在。
比如cursor变成pointer。
看着挺别扭。
可以在geo配置里加个style。
geo: {
itemStyle: {
areaColor: '#eee'
},
// 注意,这里没有cursor属性
// 光标样式得靠CSS或者zr控制
}
如果你连光标都不想变。
可以在setOption后,执行:
myChart.getZr().setCursorStyle('default');
把光标强制设为默认箭头。
这样看起来更专业。
总结一下。
做地图可视化,细节决定成败。
禁用点击不是简单的off一下。
得找到根源,精准打击。
别信那些网上抄来的代码。
多去读源码,多去测试。
遇到问题,别慌。
一步步排查,总能找到解法。
希望这篇笔记能帮到你。
少走弯路,早点下班。
毕竟,代码是写给人看的。
也是写给自己看的。
清晰,简洁,才是王道。
记得点赞收藏,下次遇到类似问题,直接翻出来看。
别等到半夜加班时,才想起来没存笔记。
那时候,真的会哭死。
好了,就说这么多。
去试试吧。
有问题评论区见。