触发谷歌标记点击监听器在标记标签点击上

Trigger google Marker click listener on marker label click

提问人:Matteo Trupia 提问时间:11/3/2023 最后编辑:Matteo Trupia 更新时间:11/4/2023 访问量:59

问:

我有一个谷歌地图应用程序,它显示一些带有自定义标签的标记。我想在用户单击标签时触发标记单击侦听器,而不仅仅是在标记图标上。但是,我找不到使用 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,
    });
}

问题在于标签不是标记的一部分,而是地图上的单独叠加层。因此,单击标签不会触发标记单击侦听器。如何使标签可点击并触发标记点击侦听器?任何帮助将不胜感激。谢谢。

javascript 事件 api-3 谷歌地图标记

评论


答:

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