我正在更新旧的 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] 元素,这没有错误,但也没有执行任何操作。
非常感谢任何帮助!
它对我有用。
错误出现在
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>