提问人:Matteo Trupia 提问时间:11/3/2023 最后编辑:Matteo Trupia 更新时间:11/4/2023 访问量:59
触发谷歌标记点击监听器在标记标签点击上
Trigger google Marker click listener on marker label click
问:
我有一个谷歌地图应用程序,它显示一些带有自定义标签的标记。我想在用户单击标签时触发标记单击侦听器,而不仅仅是在标记图标上。但是,我找不到使用 Google Maps API 执行此操作的方法。有没有办法实现这个功能?
以下是我用于创建标记和标签的代码:
// Map initialization
function initMap(mapId, centerLatitude, centerLongitude, mapZoomLevel) {
// Generate and set google maps
mapCenter = { lat: centerLatitude, lng: centerLongitude };
mapZoom = mapZoomLevel;
map = new google.maps.Map(document.getElementById(mapId), {
center: mapCenter,
...MAP_OPTIONS, // Spread '...' constant map options
zoom: mapZoom,
});
}
// The method i use to generate all the markers starting from a json
async function loadData(serializedData) {
// Convert serialized data to a JavaScript object
data = JSON.parse(serializedData);
// Iterate on each object in the dataset using map
markers = await Promise.all(
data.map(async (object) => {
// Wait for the promise returned by createMarker and return it
return await createMarker(object);
})
);
initClusterer();
}
// How i create the marker
async function createMarker(object) {
// Create marker
const marker = new google.maps.Marker({
position: object.Position,
map,
icon: getIcon(object.Direction),
label: generateMarkerLabel(object.Name)
});
// Add listener
marker.addListener("click", function () {
focusOn(marker);
ShowMarkerRouteViewBtn.click();
});
// Returns the marker created
return marker;
}
// How i create the label
function generateMarkerLabel(markerName) {
return {
text: markerName,
fontSize: "10px",
className: "marker-label"
};
}
// How i create the icon
function generateMarkerIcon(direction) {
// Generate the icon svg
let iconSvg = `
<svg xmlns="http://www.w3.org/2000/svg" xmlns:vectornator="http://vectornator.io" stroke-miterlimit="10" style="fill-rule:nonzero;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round" viewBox="0 0 36 36" xml:space="preserve" >
...[the svg paths]...
</svg>
`;
// Generate and return the marker icon literal object
return {
url: "data:image/svg+xml;charset=UTF-8," + encodeURIComponent(iconSvg),
scaledSize: new google.maps.Size(36,36),
anchor: new google.maps.Point(18, 18)
};
}
// How i init the clusterer
function initClusterer() {
clusterer = new markerClusterer.MarkerClusterer({
markers: markers,
map: map,
});
}
问题在于标签不是标记的一部分,而是地图上的单独叠加层。因此,单击标签不会触发标记单击侦听器。如何使标签可点击并触发标记点击侦听器?任何帮助将不胜感激。谢谢。
答:
1赞
Joe - Check out my books
11/3/2023
#1
编辑:
您使用的 MarkerLabel
接口将标签放在无法接受指针事件(例如单击)的窗格上。
快速破解:增加标记图标 SVG 高度,使其覆盖标签。这样,对 SVG 透明顶部的单击将充当标签本身的“人工单击”。
另一种选择:查看 js-markerwithlabel
包。
否则,请查看高级标记。这是在 2023 年及以后实施标记(+ 标签)的推荐方法。这是一个消除歧义的问题。
原答案:
您的函数返回一个 JavaScript 对象,目前尚不清楚如何将其附加到 DOM。generateMarkerLabel
但是,一旦你有了元素,你就可以将点击事件绑定到它,并委托标记的点击
事件,其中:.marker-label
// ideally attached shortly after the label element has been attached to the DOM
const mLabel = document.querySelector('.marker-label');
mLabel.addEventListener('click', (evt => {
google.maps.event.trigger(marker, 'click');
}));
评论
0赞
Matteo Trupia
11/3/2023
你好。我在分配标记常量后立即输入您的代码建议,然后运行程序。控制台打印了以下错误:TypeError: Cannot read properties of null (reading 'addEventListener')
0赞
Joe - Check out my books
11/3/2023
你如何使用这个功能?如何为它创建实际的 HTML 元素?generateMarkerLabel
0赞
Matteo Trupia
11/3/2023
我已经更新了我的应用程序以包含该过程中包含的所有部分,简而言之,我传递了一个 json,其中包含我想在地图上显示的对象的序列化数据,此时我通过设置为地图“map”来逐个生成标记,然后将它们保存在数组中以进行更多控制并将它们传递给聚类器。
0赞
Joe - Check out my books
11/3/2023
谢谢,但一个可运行的片段会更好 - 例如 stackblitz.io
0赞
Matteo Trupia
11/3/2023
我创建了一个在线项目,其中包含我正在从事的工作演示,这是链接: jsfiddle.net/matteoxt24mt/ycszru15/55
评论