最近在开发项目的过程中,使用了高德地图,算是踩的一些坑,做了一些优化
//初始化地图对象,加载地图
var map = new AMap.Map('container', { resizeEnable: true });
MAP.current = map;
for (var i = 0, marker; i < res.length; i++) {
const latitude = res[i][0] // 用户纬度
const longitude = res[i][1] // 用户经度
var marker = new AMap.Marker({
position: [ longitude, latitude],
icon: master_position,
map: map,
});
marker.content = '88888'
marker.on('click', markerClick);
marker.emit('click', { target: marker });
}
// 点击图标
function markerClick(e) {
//这里遍历将原来的其他图标设置为默认的
for (let i = 0; i < markers.length; i++) {
const ele = markers[i];
ele.setIcon(master_position);
console.log(i);
}
e.target.setIcon(master_position_active); //这里是选中的 marker 单独设置样式
infoWindow.setContent(e.target.content);
infoWindow.open(map, e.target.getPosition());
}
map.setFitView();
});
看起来好像没什么毛病 但是 最坑的地方来了
这个函数绑定的时候会直接触发,而不是等点击的时候触发 这就导致了
markerClick
这个函数里面的 for循环也会触发 如果 100条数据,就直接循环了1万次,想想就坑
既然知道了问题所在,那我们就开始来解决问题
既然每次挂载的时候就会触发
markerClick
函数,那么我们是不是可以加个状态,只有等地图都加载完成,再让我们的mackerClcik
执行 说干就干
第一步
//再原来的 for循环前面加个状态
let flag = false;
//这里遍历将原来的其他图标设置为默认的
for (let i = 0; i < markers.length; i++) {
const ele = markers[i];
ele.setIcon(master_position);
console.log(i);
}
第二步
地图加载完成 再更改 flag 状态
map.setFitView(); //这里地图完成
flag = true; //地图初始化完成 就是这一步
改完之后进行测试,好家伙,果然可以,瞬间变成 O(N)
虽然上面的已经优化了,但是还有没有优化的空间,于是我们继续改造
通过看代码,很容易发现,我们每次打开一个marker 都要把之前的所有 marker的图标重新设置一次,这无疑是一种浪费,那么我就从这入手,继续优化,
有了 想法,我们就去行动,既然我们想要的只是,打开的 marker的样式不同,那么我们是不是可以只设置当前的marker 就行了,这样就不需要 把之前的所有的 icon 都设置一遍
重要的就是,设置一个值来存储之前的 marker 状态,
ok,大功告成! 这是在项目开发中遇到的一些问题,如果大家有更好的想法,欢迎探讨!