Como de costumbre, para entender mejor lo que vamos a construir, mira el página de demostración. Asegúrese de hacer clic en las ubicaciones o en los marcadores del mapa.
Estructura del proyecto
Para este ejercicio, nuestra demostración personalizada de Google Map estará disponible en GitHub (no en CodePen). Aquí esta la estructura del proyecto:
map/ ├── index.html ├── img/ │ ├── address.svg │ ├── modal-fax.svg │ ├── modal-lat-long.svg │ ├── modal-pin.svg │ ├── modal-tel.svg │ └── pin.svg ├── main.css └── main.js
1. Andamiaje del proyecto
Antes de comenzar a crear nuestro proyecto (que se verá como una mini aplicación), hay algunas cosas que debemos tener en cuenta.
Obtenga una clave API de Google Maps
Como primera y obligatoria, deberíamos obtener una clave API de Google Maps. Para ello, debemos seguir estas instrucciones y configure un proyecto en Google Cloud Console con el API de JavaScript de mapas activado.
Para esta demostración, tomaremos prestada una clave API de una serie antigua pero aún popular llamada API de Google Maps para diseñadores. También hay un asociado manifestación de donde podemos extraer la API.
Por último, pero no menos importante, tan pronto como configure un proyecto de este tipo en Google Cloud Console, siempre es aconsejable restringir la API asociada. Por ejemplo, puede tener un solo proyecto y una API que comparte con todos los clientes de su sitio web. En tal caso, puede restringir las solicitudes de API a sitios web específicos.
Toma algunos datos
Para crear los marcadores y hacer que nuestro proyecto sea lo más realista posible, necesitaremos algunos datos del mundo real. Con esto en mente, como se mencionó anteriormente, tomaremos 13 de las ubicaciones de las oficinas de Adobe y las fijaremos en nuestro mapa.
Como veremos más adelante, cada ubicación debe incluir su latitud y longitud. Como esta información no está disponible en página de contacto de adobeusaremos el LangLong.net sitio web para recuperar sus coordenadas. Algunas de las coordenadas pueden no ser perfectamente precisas, pero entiendes el punto.
Coge algunos iconos
Para mejorar la apariencia de la demostración, necesitaremos algunos íconos.
Elementos de Envato proporciona cientos de iconos de mapa y navegación diferentes para nuestras necesidades. En este caso, elegiremos un conjunto de iconos que sigue un estilo de línea rellena. Como vimos en la estructura del proyecto, los íconos SVG seleccionados vivirán dentro del img
carpeta.

Estos son los íconos SVG que usaremos en nuestro proyecto:

Incluir archivos Bootstrap
Por último, aunque no es obligatorio, para acelerar el proceso de desarrollo, también incluiremos Bootstrap en nuestro proyecto siguiendo el enfoque de CDN, como se describe en esta página.
2. Definir el marcado de la página
Ahora que tenemos todo configurado, veamos nuestro marcado.
Archivos requeridos
A continuación, puede ver el marcado inicial con todos los archivos Bootstrap necesarios, nuestros archivos y el script
etiqueta para la API de JavaScript de Google Maps:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>A simple example showing how to build a stylish Google Map with multiple markers</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous" /> <link rel="stylesheet" href="main.css" /> </head> <body> <!-- content here --> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBSJRUNeSfHkH_ChC38jKTvjc2V7QQcOYs&language=en&callback=initMap" async></script> <script src="main.js"></script> </body> </html>
Solo echa un vistazo a la script
etiqueta para la API de JavaScript de Google Maps. Verás dos atributos:
- los
src
El atributo incluye la llamada base a la API de JavaScript de Google Maps junto con tres parámetros: dos obligatorios y uno opcional. Lo requeridokey
El parámetro almacena nuestra clave API tal como se recupera de Google Cloud Console. el opcionallanguage
El parámetro determina el idioma del mapa (nombres de ubicación, etiquetas, etc.). Lo requeridocallback
El parámetro define el nombre de la función global que se activará una vez que la API de JavaScript de Maps finalice su carga. - los
async
El parámetro le dice al navegador que descargue y ejecute el script de forma asíncrona.
Diseño personalizado de mapas de Google
Antes de echar un vistazo más de cerca a los elementos de la página, analicemos los requisitos de diseño.
- En pantallas móviles (<768px), el diseño será así:

- En pantallas medianas y grandes (≥768px), habrá dos columnas de igual ancho:

- En cada caso, el mapa cubrirá la altura de la ventana.
Aquí está el marcado asociado lleno de clases auxiliares de Bootstrap:
<div class="container-fluid"> <div class="row align-items-center"> <div class="col-md-6 mt-5 mb-3"> <h1 class="mb-4"> Some of <a href="https://www.adobe.com/about-adobe/contact/offices.html" class="text-body" target="_blank">Adobe's office locations</a> </h1> <div class="block"> <h2 class="mb-3">North America</h2> <div class="row"> <div class="col-sm-6 mb-2"> <div class="d-flex align-items-center"> <img width="24" height="24" src="img/address.svg" alt="" class="me-2" /> <a href="" class="location text-body" data-index="0">Corporate headquarters</a> </div> </div> <div class="col-sm-6 mb-2"> <div class="d-flex align-items-center"> <img width="24" height="24" src="img/address.svg" alt="" class="me-2" /> <a href="" class="location text-body" data-index="1">Los Angeles</a> </div> </div> </div> <hr /> </div> <!-- more blocks here --> </div> <div class="col-md-6 p-0"> <div id="map" class="vh-100"></div> </div> </div> </div>
Lo más importante, observe dos cosas:
- Cada enlace de ubicación, que representa una ubicación de Adobe, viene con el
data-index
atributo. Tenga en cuenta este atributo, ya que lo usaremos más adelante. - Hay un elemento vacío con el
map
IDENTIFICACIÓN. Esto incluirá los contenidos del mapa y se generará a través de JavaScript.
3. Agregar el JavaScript
En este punto, estamos listos para construir la funcionalidad central de nuestro proyecto personalizado de Google Map. ¡Vamos a hacerlo!
Ubicaciones de las tiendas
Capturamos las ubicaciones en el marcado, pero también las necesitamos en JavaScript. Entonces, almacenémoslos en una matriz como esta:
const pins = [ { location: "North America", name: "Corporate headquarters", address: "345 Park Avenue <br> San Jose, CA 95110-2704", tel: "408-536-2800", fax: "408-537-6000", lat: 37.33078, long: -121.892357, }, { location: "North America", name: "Los Angeles", address: "(former Magento office) <br> 3640 Holdrege Ave <br> Los Angeles, CA 90016", lat: 34.01989, long: -118.37811, }, // more locations here ];
Tenga en cuenta que conservamos el orden en que aparecen las ubicaciones tanto en el marcado como en el objeto. Un lugar con la data-index="0"
en el marcado denota que la misma ubicación debe estar en el primer lugar de la pins
formación.
Nota: en un escenario del mundo real, probablemente habría un lenguaje de fondo para administrar todas las ubicaciones en un solo lugar. Por ejemplo, si está familiarizado con WordPress y el ACFPRO complemento, probablemente tendrá un contenido flexible o un reloj de repetición campo donde pones todas las ubicaciones. En su interior, habrá campos adicionales para administrar los detalles de la ubicación. Especialmente para obtener las coordenadas de cada ubicación, puede tener una Mapa de Google campo. Entonces, a través de la wp_localize_script()
puede pasar las ubicaciones en JavaScript y crear un objeto similar al que tenemos aquí.
Inicializar mapa de Google personalizado
A continuación, inicializaremos el mapa a través del initMap()
que mostramos antes.
Nuestro mapa tendrá las siguientes personalizaciones:
- Tendrá su centro en Londres, Reino Unido.
- tendrá
zoom: 3
para ver tantas ubicaciones como sea posible de forma predeterminada. - Personalizaremos sus estilos predeterminados a través de esta herramientapero siempre puedes optar por cestilo de mapa basado en ruido. En particular, cambiaremos el color predeterminado del agua de esta manera:

Con todo lo anterior en mente, aquí está el cuerpo inicial de nuestra función:
// London, UK const center = { lat: 51.507351, lng: -0.127758 }; const styles = [ { featureType: "poi", stylers: [ { visibility: "off" } ] }, { featureType: "water", stylers: [ { color: "#39C3FC" } ] } ]; function initMap() { const map = new google.maps.Map(document.getElementById("map"), { center, styles, zoom: 3 }); }
Crear marcadores de mapas de Google
Dentro de initMap()
función, también llamaremos a la createMarkers()
función para crear los marcadores de ubicación:
function initMap() { // map declaration here createMarkers(map); }
Dentro de esta función, haremos lo siguiente:
- Inicialice una ventana de información que mostrará información sobre un marcador cada vez que alguien haga clic en él.
- Reemplace el ícono de marcador predeterminado con uno SVG personalizado.

- Recorra las ubicaciones y colóquelas en el mapa según sus coordenadas. Además, haz que aparezcan con una animación DROP.
- Guarde cada instancia de marcador en el
markers
formación. Veremos por qué más tarde.
Aquí está la declaración de la función:
function createMarkers(map) { const infowindow = new google.maps.InfoWindow(); const markerIcon = { url: "img/pin.svg", scaledSize: new google.maps.Size(40, 40) }; for (let i = 0; i < pins.length; i++) { const marker = new google.maps.Marker({ position: { lat: pins[i].lat, lng: pins[i].long }, map, icon: markerIcon, animation: google.maps.Animation.DROP }); markers.push(marker); } }
Alternar ventana de información
Dentro de createMarkers()
función, también registraremos un click
evento para cada marcador.
function createMarkers(map) { ... for (let i = 0; i < pins.length; i++) { // marker here google.maps.event.addListener(marker, "click", function () { infowindow.setContent(createInfoWindowContent(pins[i])); map.setCenter(marker.getPosition()); infowindow.open(map, marker); const targetLocation = document.querySelector(`[data-index="${i}"]`); if (document.querySelector(".location.active")) { document .querySelector(".location.active") .classList.remove(activeClass); } targetLocation.classList.add(activeClass); scroll({ top: targetLocation.offsetTop, behavior: "smooth" }); }); } }
Cada vez que un usuario haga clic en un marcador, realizaremos las siguientes acciones:
- Rellene el contenido de la ventana de información con contenidos asociados con este marcador gracias a la
createInfoContent()
función. - Establezca el centro del mapa en función de las coordenadas de este marcador.
- Mostrar la ventana de información.
- Quitar el
active
class desde cualquier enlace de ubicación asociado, si lo hay. - Encuentre el enlace de ubicación cuyo índice coincida con el índice de este marcador y asígnele el
active
clase. Esto le dará al enlace de destino un color de fondo azul.

- Desplazamiento suave hasta el enlace de la ubicación correspondiente.
Llenar ventana de información
Como dijimos, el trabajo del createInfoContent()
La función será alimentar la ventana de información con el contenido del marcador en el que se hizo clic.
Usaremos marcado directo para mostrar el contenido de cada marcador. Dado que algunas ubicaciones no siempre tienen todos los detalles, aplicaremos algunas comprobaciones para asegurarnos de que nuestro marcado no se infle.

Aquí está la declaración de la función:
function createInfoWindowContent(pin) { let phoneString = ""; let faxString = ""; let latLongString = ""; let addressString = ""; if (pin.tel) { phoneString = ` <p class="d-flex align-items-center"> <img class="me-2" width="24" height="24" src="https://webdesign.tutsplus.com/tutorials/img/modal-tel.svg" alt=""> ${pin.tel} </p> `; } if (pin.fax) { faxString = ` <p class="d-flex align-items-center"> <img class="me-2" width="24" height="24" src="img/modal-fax.svg" alt=""> ${pin.fax} </p> `; } if (pin.lat && pin.long) { latLongString = ` <p class="d-flex align-items-center"> <img class="me-2" width="24" height="24" src="img/modal-lat-long.svg" alt=""> ${pin.lat}, ${pin.long} </p> `; } if (pin.address) { addressString = ` <div class="d-flex"> <img class="me-2" width="24" height="24" src="img/modal-pin.svg" alt=""> ${pin.address} </div> `; } const contentString = ` <h3 class="fs-4 text">${pin.name}</h3> <hr> ${phoneString} ${faxString} ${latLongString} ${addressString} `; return contentString; }
Enlaces de ubicación
Discutimos lo que debería suceder cuando se hace clic en un marcador. Pero también necesitamos aplicar alguna funcionalidad cuando sucede lo contrario. En otras palabras, queremos asegurarnos de que cada vez que un usuario haga clic en un enlace de ubicación, se mostrará el marcador correspondiente. hizo clic
Otra función, la showLocations()
one, será responsable de manejar esta funcionalidad. Esto también vivirá dentro del initMap()
función.
Entonces, cada vez que se haga clic en un enlace de ubicación, realizaremos las siguientes acciones:
- Cancele su comportamiento predeterminado.
- Quitar el
active
clase desde cualquier enlace de ubicación, si lo hay. - Añade el
active
clase a este enlace. - Desplazamiento suave al mapa.
- Encuentre el marcador cuyo índice coincida con el índice de este enlace y active su
click
evento. Podemos apuntar al marcador especificado porque lo hemos almacenado en un paso anterior dentro delmarkers
formación.
Aquí está la definición de la función:
function showLocations() { const locations = document.querySelectorAll(".location"); locations.forEach((location) => { location.addEventListener("click", function (e) { e.preventDefault(); if (document.querySelector(".location.active")) { document .querySelector(".location.active") .classList.remove(activeClass); } location.classList.add(activeClass); scroll({ top: document.getElementById("map").offsetTop, behavior: "smooth" }); new google.maps.event.trigger(markers[this.dataset.index], "click"); }); }); }
Conclusión
¡Y hemos terminado! Este fue un viaje bastante largo, pero espero que lo hayas disfrutado y que te haya ayudado a mejorar tus habilidades con respecto a la API de JavaScript de Google Maps.
Una vez más, ¡no olvide poner su propia clave para la prueba del proyecto en vivo! Aquí esta la enlace del proyecto.
Las cosas no se detienen aquí. Podemos continuar mejorando/ampliando este proyecto haciendo varias cosas, por ejemplo:
- Colóquelos en grupos de marcadores de mesa para agrupar marcadores. Esta es una buena adición, especialmente para los casos en los que hay muchos marcadores.
- Dinamice este proyecto utilizando WordPress y ACF PRO, como se explica en algunas secciones anteriores. Dependiendo de cómo vaya este proyecto, probablemente volveré con un tutorial de este tipo en el futuro 🙂
- Restrinja los límites del mapa para evitar mostrar un área gris durante el arrastre o el alejamiento.

Como siempre, ¡muchas gracias por leer!