腾讯地图 聚合点下的Marker点击事件
自己开发项目遇到的小问题:
1、聚合点下如何添加Marker点的点击事件
2、腾讯地图的实例是H5的自己实力不济转成vue的时候会出现报错,大家可以一起探讨
关键点:
1、在创建点标记图层后才可以设置点击事件
marker = new TMap.MultiMarker
//监听marker点击事件
marker.on("click", eventClick)
//创建点击事件
var eventClick = function (evt) { console.log(evt.geometry.id) }
接下来是代码(H5)复制粘贴就能用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>自定义点聚合功能</title>
<style>
html,
body {
margin: 0;
padding: 0;
overflow: hidden;
height: 100%;
}
#mapContainer {
position: relative;
height: 100%;
width: 100%;
}
.clusterBubble {
border-radius: 50%;
color: #fff;
font-weight: 500;
text-align: center;
opacity: 0.88;
background-image: linear-gradient(139deg, #ff3d66 0%, #ff3574 100%);
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.20);
position: absolute;
top: 0px;
left: 0px;
}
.locicon {
position: absolute;
bottom: 20px;
right: 15px;
width: 50px;
height: 50px;
z-index: 10000;
}
</style>
</head>
<script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77"></script>
<body onload="init()">
<div id='mapContainer'></div>
<img class="locicon" onclick="setCenter()" src="./icon_location_s.png" alt="">
<script>
var map;
var center = new TMap.LatLng(39.953416, 116.380945);
var ClusterBubbleClick;
function init() {
var drawContainer = document.getElementById('mapContainer');
map = new TMap.Map('mapContainer', {
zoom: 16.5,
minZoom: 10, //此处设置地图的缩放级别 最小值
maxZoom: 17, //此处设置地图的缩放级别 最大值
pitch: 0,
center: center,
mapStyleId: 'style 1'
});
// 创建点聚合
var markerCluster = new TMap.MarkerCluster({
id: 'cluster',
map: map,
enableDefaultStyle: false, // 关闭默认样式
minimumClusterSize: 3,
geometries: [{ // 点数组
position: new TMap.LatLng(39.953416, 116.480945)
},
{
position: new TMap.LatLng(39.984104, 116.407503)
},
{
position: new TMap.LatLng(39.908802, 116.497502)
},
{
position: new TMap.LatLng(40.040417, 116.373514)
},
{
position: new TMap.LatLng(39.953416, 116.380945)
},
{
position: new TMap.LatLng(39.984104, 116.307503)
},
{
position: new TMap.LatLng(39.908802, 116.397502)
},
{
position: new TMap.LatLng(40.040417, 116.273514)
},
],
zoomOnClick: true,
gridSize: 60,
averageCenter: false
});
var clusterBubbleList = [];
var markerGeometries = [];
var marker = null;// 监听聚合簇变化
markerCluster.on('cluster_changed', function (e) {
// 销毁旧聚合簇生成的覆盖物
if (clusterBubbleList.length) {
clusterBubbleList.forEach(function (item) {
item.destroy();
})
clusterBubbleList = [];
}
markerGeometries = [];
// 根据新的聚合簇数组生成新的覆盖物和点标记图层
var clusters = markerCluster.getClusters();
clusters.forEach(function (item) {
if (item.geometries.length > 1) {
let clusterBubble = new ClusterBubble({
map,
position: item.center,
content: item.geometries.length,
});
clusterBubble.on('click', () => {
map.fitBounds(item.bounds);
});
clusterBubbleList.push(clusterBubble);
} else {
markerGeometries.push({
position: item.center
});
}
});
if (marker) {
// 已创建过点标记图层,直接更新数据
marker.setGeometries(markerGeometries);
} else {
// 创建点标记图层
marker = new TMap.MultiMarker({
map,
styles: {
default: new TMap.MarkerStyle({
'width': 50,
'height': 50,
'anchor': {
x: 17,
y: 21,
},
'src': 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGoAAABqCAYAAABUIcSXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQ4IDc5LjE2NDAzNiwgMjAxOS8wOC8xMy0wMTowNjo1NyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIxLjAgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjNEODU1NjU4OTA2MzExRUI4Mzc1OUFGOTRDN0Y3RjkzIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjNEODU1NjU5OTA2MzExRUI4Mzc1OUFGOTRDN0Y3RjkzIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6M0Q4NTU2NTY5MDYzMTFFQjgzNzU5QUY5NEM3RjdGOTMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6M0Q4NTU2NTc5MDYzMTFFQjgzNzU5QUY5NEM3RjdGOTMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz72q6iNAAASP0lEQVR42uxda2wc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',
}),
},
geometries: markerGeometries
});
//监听marker点击事件
marker.on("click", eventClick)
}
});
var eventClick = function (evt) {
console.log(evt.geometry.id)
}
//添加坐标
markerCluster.updateGeometries(
[
{
"styleId": "marker",
"id": "4",
"position": new TMap.LatLng(39.994104, 116.287503),
}
]
)
var circle = new TMap.MultiCircle({
map,
styles: {
// 设置圆形样式
circle: new TMap.CircleStyle({
color: 'rgba(255, 61, 102, 0.08)',
showBorder: true,
borderColor: 'rgba(255,255,255,1)',
borderWidth: 1
})
},
geometries: [
{
styleId: 'circle',
center: center,
radius: 200
}
]
})
}
// 以下代码为基于DOMOverlay实现聚合点气泡
//设置地图中心点事件
function setCenter() {
map.easeTo({ zoom: 16.5, rotation: 0, center: center }, { duration: 1000 });//平滑缩放,旋转到指定级别
}
function ClusterBubble(options) {
TMap.DOMOverlay.call(this, options);
}
ClusterBubble.prototype = new TMap.DOMOverlay();
ClusterBubble.prototype.onInit = function (options) {
this.content = options.content;
this.position = options.position;
};
// 销毁时需要删除监听器
ClusterBubble.prototype.onDestroy = function () {
this.dom.removeEventListener('click', this.onClick);
this.removeAllListeners();
};
ClusterBubble.prototype.onClick = function () {
this.emit('click');
};
// 创建气泡DOM元素
ClusterBubble.prototype.createDOM = function () {
var dom = document.createElement('div');
dom.classList.add('clusterBubble');
dom.innerText = this.content;
dom.style.cssText = [
'width: ' + (40 + parseInt(this.content) * 2) + 'px;',
'height: ' + (40 + parseInt(this.content) * 2) + 'px;',
'line-height: ' + (40 + parseInt(this.content) * 2) + 'px;',
].join(' ');
// 监听点击事件,实现zoomOnClick
this.onClick = this.onClick.bind(this);
dom.addEventListener('click', this.onClick);
return dom;
};
ClusterBubble.prototype.updateDOM = function () {
if (!this.map) {
return;
}
// 经纬度坐标转容器像素坐标
let pixel = this.map.projectToContainer(this.position);
// 使文本框中心点对齐经纬度坐标点
let left = pixel.getX() - this.dom.clientWidth / 2 + 'px';
let top = pixel.getY() - this.dom.clientHeight / 2 + 'px';
this.dom.style.transform = `translate(${left}, ${top})`;
this.emit('dom_updated');
};
window.ClusterBubble = ClusterBubble;
</script>
</body>
</html>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下