如果您的版面配置會在 Place Details 檢視畫面顯示時變更,請使用事件監聽器 placedetailsviewshowstart 和 placedetailsviewhidestart。在下例中,有三個以自訂標記表示的區域。當使用者按下其中一個區域標記時,系統會開啟 InfoWindow 來說明該區域。如果使用者在 InfoWindow 開啟時點選搜尋點,InfoWindow 就會在搜尋點的 Place Details 檢視畫面顯示時關閉,並在使用者關閉 Place Details 檢視畫面時重新開啟。
查看原始碼
TypeScript
let map: google.maps.Map;
let infoWindow;
let infoStorage;
const districts = {
a: {
label: "1",
location: {
lat: -1.283975,
lng: 36.818797,
},
name: "Central",
description:
"The Central Business District is a hub of economic activity during the day and a destination for great food at night.",
},
b: {
label: "2",
location: {
lat: -1.270955,
lng: 36.810857,
},
name: "Westlands",
description:
"With many high-end restaurants and a vibrant nightlife, Westlands attracts young professionals and their families. ",
},
c: {
label: "3",
location: {
lat: -1.311868,
lng: 36.838624,
},
name: "South",
description:
"Known for high-rise apartment buildings, South B and South C are in high demand.",
},
};
function initMap() {
const localContextMapView = new google.maps.localContext.LocalContextMapView({
element: document.getElementById("map"),
placeTypePreferences: [
{ type: "restaurant" },
{ type: "tourist_attraction" },
],
maxPlaceCount: 12,
});
map = localContextMapView.map!;
map.setOptions({
center: districts["a"].location,
zoom: 13,
});
// Add 3 custom markers that open InfoWindows on click
for (const key in districts) {
const district = districts[key];
const marker = new google.maps.Marker({
label: district.label,
position: district.location,
map: map,
zIndex: 30,
});
marker.addListener("click", () => {
// Close any open details or existing InfoWindows
localContextMapView.hidePlaceDetailsView();
if (infoWindow) {
infoWindow.close();
}
// Create and open a new InfoWindow
createInfoWindow(district, marker);
// Define origin as the selected marker position
localContextMapView.directionsOptions = {
origin: district.location,
};
});
}
// Set the LocalContextMapView event handlers.
localContextMapView.addListener("placedetailsviewshowstart", () => {
if (infoWindow) {
infoWindow.close();
}
});
localContextMapView.addListener("placedetailsviewhidestart", () => {
if (infoStorage) {
createInfoWindow(infoStorage.district, infoStorage.marker);
}
});
}
// Creates an infoWindow and also stores information associated with the
// InfoWindow so the InfoWindow can be restored after it has been closed
// by non-user-initiated events.
function createInfoWindow(district, marker) {
// Build the content of the InfoWindow
const contentDiv = document.createElement("div");
const nameDiv = document.createElement("div");
const descriptionDiv = document.createTextNode(district.description);
contentDiv.classList.add("infowindow-content");
nameDiv.classList.add("title");
nameDiv.textContent = district.name;
descriptionDiv.textContent = district.description;
contentDiv.appendChild(nameDiv);
contentDiv.appendChild(descriptionDiv);
// Create and open a new InfoWindow
infoWindow = new google.maps.InfoWindow();
infoWindow.setContent(contentDiv);
infoWindow.open(map, marker);
// Store key properties of the InfoWindow for future restoration
infoStorage = {
district: district,
marker: marker,
};
// Clear content storage if infoWindow is closed by the user
infoWindow.addListener("closeclick", () => {
if (infoStorage) {
infoStorage = null;
}
});
}
declare global {
interface Window {
initMap: () => void;
}
}
window.initMap = initMap;
let map;
let infoWindow;
let infoStorage;
const districts = {
a: {
label: "1",
location: {
lat: -1.283975,
lng: 36.818797,
},
name: "Central",
description:
"The Central Business District is a hub of economic activity during the day and a destination for great food at night.",
},
b: {
label: "2",
location: {
lat: -1.270955,
lng: 36.810857,
},
name: "Westlands",
description:
"With many high-end restaurants and a vibrant nightlife, Westlands attracts young professionals and their families. ",
},
c: {
label: "3",
location: {
lat: -1.311868,
lng: 36.838624,
},
name: "South",
description:
"Known for high-rise apartment buildings, South B and South C are in high demand.",
},
};
function initMap() {
const localContextMapView = new google.maps.localContext.LocalContextMapView({
element: document.getElementById("map"),
placeTypePreferences: [
{ type: "restaurant" },
{ type: "tourist_attraction" },
],
maxPlaceCount: 12,
});
map = localContextMapView.map;
map.setOptions({
center: districts["a"].location,
zoom: 13,
});
// Add 3 custom markers that open InfoWindows on click
for (const key in districts) {
const district = districts[key];
const marker = new google.maps.Marker({
label: district.label,
position: district.location,
map: map,
zIndex: 30,
});
marker.addListener("click", () => {
// Close any open details or existing InfoWindows
localContextMapView.hidePlaceDetailsView();
if (infoWindow) {
infoWindow.close();
}
// Create and open a new InfoWindow
createInfoWindow(district, marker);
// Define origin as the selected marker position
localContextMapView.directionsOptions = {
origin: district.location,
};
});
}
// Set the LocalContextMapView event handlers.
localContextMapView.addListener("placedetailsviewshowstart", () => {
if (infoWindow) {
infoWindow.close();
}
});
localContextMapView.addListener("placedetailsviewhidestart", () => {
if (infoStorage) {
createInfoWindow(infoStorage.district, infoStorage.marker);
}
});
}
// Creates an infoWindow and also stores information associated with the
// InfoWindow so the InfoWindow can be restored after it has been closed
// by non-user-initiated events.
function createInfoWindow(district, marker) {
// Build the content of the InfoWindow
const contentDiv = document.createElement("div");
const nameDiv = document.createElement("div");
const descriptionDiv = document.createTextNode(district.description);
contentDiv.classList.add("infowindow-content");
nameDiv.classList.add("title");
nameDiv.textContent = district.name;
descriptionDiv.textContent = district.description;
contentDiv.appendChild(nameDiv);
contentDiv.appendChild(descriptionDiv);
// Create and open a new InfoWindow
infoWindow = new google.maps.InfoWindow();
infoWindow.setContent(contentDiv);
infoWindow.open(map, marker);
// Store key properties of the InfoWindow for future restoration
infoStorage = {
district: district,
marker: marker,
};
// Clear content storage if infoWindow is closed by the user
infoWindow.addListener("closeclick", () => {
if (infoStorage) {
infoStorage = null;
}
});
}
window.initMap = initMap;
/*
* Always set the map height explicitly to define the size of the div element
* that contains the map.
*/
#map {
height: 100%;
}
/*
* Optional: Makes the sample page fill the window.
*/
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
.infowindow-content {
width: 300px;
}
.title {
font-size: x-large;
font-weight: bold;
}
<html>
<head>
<title>Local Context Events</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<link rel="stylesheet" type="text/css" href="./style.css" />
<script type="module" src="./index.js"></script>
</head>
<body>
<div id="map"></div>
<!--
The `defer` attribute causes the callback to execute after the full HTML
document has been parsed. For non-blocking uses, avoiding race conditions,
and consistent behavior across browsers, consider loading using Promises.
See https://developers.google.com/maps/documentation/javascript/load-maps-js-api
for more information.
-->
<script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&libraries=localContext&v=beta"
defer
></script>
</body>
</html>
當 Place Details 檢視畫面開啟且您呼叫 InfoWindow.close() 時,開啟的 InfoWindow 就會從 DOM 中移除。如要建立「重新開啟」InfoWindow 的效果,您必須將 InfoWindow 的屬性儲存在 DOM 外部的變數中,以便在希望 InfoWindow 恢復顯示時重新建立。建議在建立 InfoWindow 時,將資訊儲存到儲存空間變數。
let infoStorage;
function createInfoWindow(district, marker) {
// Build the content of the InfoWindow
let contentDiv = document.createElement('div');
...
// Create and open a new InfoWindow
infoWindow = new google.maps.InfoWindow();
infoWindow.setContent(contentDiv);
infoWindow.open(map, marker);
// Store key properties of the InfoWindow for future restoration
infoStorage = {
'district': district,
'marker': marker,
};
}
之後當 Place Details 檢視畫面關閉時,您可以呼叫相同的 InfoWindow 建立函式,重新建立最後開啟的 InfoWindow。