从 HTML 链接触发 Google 地图高级标记闪烁

问题描述 投票:0回答:1

我正在更新旧的 Google 地图脚本以使用新的高级标记格式。 根据一系列位置动态生成标记、将它们显示在地图上以及使它们可以通过信息窗口单击,一切都运行良好。 我无法翻译的一项功能是能够单击 HTML 链接并让它触发标记单击,以便打开相应的信息窗口。

就上下文而言,这是目录的一部分。 当用户搜索时,搜索结果上方会显示带有所有标记的地图,下面还有结果的文本列表。 在每个搜索结果中,我们需要一个“在地图上查看”链接,如果用户单击该链接,它将触发相应标记的单击并显示信息窗口。

使用旧版本的标记,我们能够在创建每个标记时将其推送到名为 mapMarkers 的数组上,然后我们将此函数绑定到 HTML 链接,这些链接都具有 goToMarker 类:

$('.goToMarker').on('click', function () {
    google.maps.event.trigger(mapMarkers[$(this).data('markerindex')], 'click');
});

同样的方法对我来说在新版本中不起作用。 这是我当前的代码(这是在 C# Razor 视图中,一些值是从变量填充的;我还意识到我最终需要一种方法将结果 ID 绑定回其特定标记,但现在我只是针对第一个全面索引为 0 的标记尝试获得概念证明):

        <script>
            (g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]") ?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })
                ({ key:'@(ConfigurationManager.AppSettings["GoogleMapsAPIKey"])', v: "weekly" });
        </script>

        <script>
            var mapMarkers = [];
            let map;

            async function initMap() {
                const { Map, InfoWindow } = await google.maps.importLibrary("maps");
                const { AdvancedMarkerElement, PinElement } = await google.maps.importLibrary("marker");

                const map = new Map(document.getElementById("map"), {
                    center: { lat: @Model.searchConfigMap.centerLat, lng: @Model.searchConfigMap.centerLong },
                    zoom: 6,
                    minZoom: 1,
                    maxZoom: 20,
                    mapTypeId: 'roadmap',
                    gestureHandling: 'cooperative',
                    mapId: 'AMRPA_REHAB_HOSPITALS',
                });

                //array of hospital locations
                const arrHospitals = @Html.Raw(JsonConvert.SerializeObject(arrHospitals));

                //create shared info window
                const infoWindow = new InfoWindow();

                //fontawesome icon for glyph
                const icon = document.createElement("div");
                icon.innerHTML = '<i class="fa fa-pizza-slice fa-lg"></i>';

                //create markers
                arrHospitals.forEach(({ position, title, infoText }, i) => {
                    const pin = new PinElement({
                        glyphColor: "#FFFFFF",
                        background: "#9d2235",
                        borderColor: "#9d2235",
                        scale: .8,
                    });

                    const marker = new AdvancedMarkerElement({
                        position,
                        map,
                        title: `${title}`,
                        content: pin.element,
                        gmpClickable: true,
                    });

                    //add click listener for each marker and set up info window.
                    marker.addListener("click", ({ domEvent, latLng }) => {
                        const { target } = domEvent;

                        infoWindow.close();
                        //infoWindow.setContent(marker.content);
                        infoWindow.setContent(buildContent(infoText));
                        infoWindow.open(marker.map, marker);
                    });

                    mapMarkers.push(marker);
                });
            }

            initMap();

            function buildContent(infoText) {
                const content = document.createElement("div");
                content.classList.add('infoText');
                content.innerHTML = infoText;

                return content;
            }

            function goToMarker() {
                try {
                    //alert('clicked!');
                    alert(mapMarkers.length);
                    alert(mapMarkers[0]);
                    //mapMarkers[0].click();
                    google.maps.event.trigger(mapMarkers[0], 'click');
                }
                catch (error) {
                    console.log(error);
                }
            }
        </script>

当我单击其中一个 HTML 链接时,我在控制台中收到此错误:

TypeError: Cannot destructure property 'domEvent' of 'undefined' as it is undefined.
    at aR.<anonymous> (rehabhospitaldirectory:820:52)
    at _.Kk [as trigger] (main.js:141:94)
    at goToMarker (rehabhospitaldirectory:849:39)
    at HTMLAnchorElement.onclick (rehabhospitaldirectory:887:58)

我还尝试直接触发单击 mapMarkers[0] 元素,这没有错误,但也没有执行任何操作。

非常感谢任何帮助!

google-maps google-maps-api-3 google-maps-markers google-maps-advanced-marker-element
1个回答
0
投票

它对我有用。

错误出现在

goToMarker
函数中,但根据您共享的代码,您没有在任何地方调用该函数。

通过 jQuery 选择器的触发器应该可以工作。我的猜测是,您仍在从 HTML 链接本身调用

goToMarker
函数,这没有意义,但这部分代码在您的问题中缺失了

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps");
  const { AdvancedMarkerElement } = await google.maps.importLibrary("marker");
  const map = new Map(document.getElementById("map"), {
    center: {
      lat: 37.42,
      lng: -122.1
    },
    zoom: 14,
    mapId: "4504f8b37365c3d0",
  });

  const marker = new AdvancedMarkerElement({
    map,
    position: {
      lat: 37.42,
      lng: -122.1
    },
  });

  marker.addListener('click', function() {
    alert('CLICKED')
  })

  const link = document.getElementById('link')

  link.addEventListener('click', () => {
    google.maps.event.trigger(marker, 'click')
  })
}

initMap();
#map {
  margin-top: 10px;
  height: 150px;
}
<a id="link" href="#">CLICK ME</a>
<div id="map"></div>

<!-- prettier-ignore -->
<script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
        ({key: "AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk", v: "weekly"});</script>

© www.soinside.com 2019 - 2024. All rights reserved.