Custom Popups
by Chris Ball
HTML
<div id="map"></div>
<div id="content">
Hello world!
</div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap">
</script>
CSS
/* 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;
}
/* The popup bubble styling. */
.popup-bubble {
/* Position the bubble centred-above its parent. */
position: absolute;
top: 0;
left: 0;
transform: translate(-50%, -100%);
/* Style the bubble. */
background-color: transparent;
padding: 5px;
font-family: sans-serif;
overflow-y: auto;
max-height: 60px;
}
/* The parent of the bubble. A zero-height div at the top of the tip. */
.popup-bubble-anchor {
/* Position the div a fixed distance above the tip. */
position: absolute;
width: 100%;
bottom: /* TIP_HEIGHT= */ 8px;
left: 0;
}
/* This element draws the tip. */
.popup-bubble-anchor::after {
content: "";
position: absolute;
top: 0;
left: 0;
/* Center the tip horizontally. */
transform: translate(-50%, 0);
/* The tip is a https://css-tricks.com/snippets/css/css-triangle/ */
width: 0;
height: 0;
/* The tip is 8px high, and 12px wide. */
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: /* TIP_HEIGHT= */ 8px solid white;
}
/* JavaScript will position this div at the bottom of the popup tip. */
.popup-container {
cursor: auto;
height: 0;
position: absolute;
/* The max width of the info window. */
width: 200px;
}
JavaScript
var map, popup, Popup;
/** Initializes the map and the custom popup. */
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -33.9, lng: 151.1},
zoom: 10,
});
Popup = createPopupClass();
popup = new Popup(
new google.maps.LatLng(-33.866, 151.196),
document.getElementById('content'));
popup.setMap(map);
}
/**
* Returns the Popup class.
*
* Unfortunately, the Popup class can only be defined after
* google.maps.OverlayView is defined, when the Maps API is loaded.
* This function should be called by initMap.
*/
function createPopupClass() {
/**
* A customized popup on the map.
* @param {!google.maps.LatLng} position
* @param {!Element} content The bubble div.
* @constructor
* @extends {google.maps.OverlayView}
*/
function Popup(position, content) {
this.position = position;
content.classList.add('popup-bubble');
// This zero-height div is positioned at the bottom of the bubble.
var bubbleAnchor = document.createElement('div');
bubbleAnchor.classList.add('popup-bubble-anchor');
bubbleAnchor.appendChild(content);
// This zero-height div is positioned at the bottom of the tip.
this.containerDiv = document.createElement('div');
this.containerDiv.classList.add('popup-container');
this.containerDiv.appendChild(bubbleAnchor);
// Optionally stop clicks, etc., from bubbling up to the map.
google.maps.OverlayView.preventMapHitsAndGesturesFrom(this.containerDiv);
}
// ES5 magic to extend google.maps.OverlayView.
Popup.prototype = Object.create(google.maps.OverlayView.prototype);
/** Called when the popup is added to the map. */
Popup.prototype.onAdd = function() {
this.getPanes().floatPane.appendChild(this.containerDiv);
};
/** Called when the popup is removed from the map. */
Popup.prototype.onRemove = function() {
if (this.containerDiv.parentElement) {
...