Eventos

Organiza tus páginas con colecciones Guarda y categoriza el contenido según tus preferencias.
Seleccionar plataforma: Android iOS JavaScript

En esta página, se describen los eventos de la interfaz de usuario y los errores que puedes escuchar y controlar de manera programática.

Eventos de interfaz de usuario

JavaScript dentro del navegador es controlado por eventos, lo que significa que responde a interacciones generando eventos y espera que un programa escuche eventos interesantes. Existen dos tipos de eventos:

  • Los eventos de usuario (como los eventos de mouse) se propagan del DOM a la API de Maps JavaScript. Estos eventos son independientes y distintos de los eventos de DOM estándar.
  • Las notificaciones de cambio de estado de MVC reflejan cambios en los objetos de la API de Maps JavaScript y se nombran mediante una convención property_changed.

Cada objeto de la Maps JavaScript API exporta varios eventos con nombre. Los programas interesados en ciertos eventos registrarán objetos de escucha de eventos de JavaScript para esos eventos y ejecutarán código cuando se reciban llamando a addListener() para registrar controladores de eventos en el objeto.

En el siguiente ejemplo, se muestran los eventos que activa google.maps.Map a medida que interactúas con el mapa.

Para obtener una lista completa de eventos, consulta la referencia de la API de Maps JavaScript. Los eventos se mencionan en una sección separada para cada objeto que contenga eventos.

Eventos de la IU

Algunos objetos de la API de Maps JavaScript están diseñados para responder a los eventos de los usuarios, como los eventos del mouse o del teclado. Por ejemplo, estos son algunos de los eventos de usuario que un objeto google.maps.Marker puede escuchar:

  • 'click'
  • 'dblclick'
  • 'mouseup'
  • 'mousedown'
  • 'mouseover'
  • 'mouseout'

Para ver la lista completa, consulta la clase Marker. Estos eventos pueden parecer eventos de DOM estándar, pero en realidad forman parte de la API de Maps JavaScript. Dado que distintos navegadores implementan diferentes modelos de eventos de DOM, la API de Maps JavaScript proporciona estos mecanismos para detectar eventos de DOM y responder a ellos sin necesidad de manejar las diversas peculiaridades de los navegadores. Por lo general, estos eventos también pasan argumentos dentro del evento en los que se indica algún estado de la IU (como la posición del mouse).

Cambios de estado de MVC

Los objetos de MVC normalmente contienen estados. Cuando cambie la propiedad de un objeto, la API de Maps JavaScript activará un evento que se haya modificado. Por ejemplo, la API activará un evento zoom_changed en un mapa cuando cambie el nivel de zoom del mapa. Puedes interceptar estos cambios de estado si llamas a addListener() para registrar también los controladores de eventos en el objeto.

Los eventos de usuario y los cambios de estado de MVC pueden ser similares, pero, por lo general, deseas tratarlos de manera diferente en tu código. Los eventos de MVC, por ejemplo, no pasan argumentos dentro de su evento. Te recomendamos inspeccionar la propiedad que cambió en un cambio de estado de MVC llamando al método getProperty apropiado en ese objeto.

Cómo administrar eventos

Si deseas registrarte para recibir notificaciones de eventos, usa el controlador de eventos addListener(). Ese método toma un evento para detectar y una función para llamar cuando se produce el evento especificado.

Ejemplo: eventos de mapas y marcadores

En el código siguiente se combinan eventos de usuario y eventos de cambio de estado. Se adjunta un controlador de eventos a un marcador que aplica zoom al mapa cuando se hace clic en él. También agregamos un controlador de eventos al mapa para realizar cambios en la propiedad center y desplazar el mapa de nuevo al marcador después de 3 segundos después de recibir el evento center_changed:

TypeScript

function initMap(): void {
  const myLatlng = { lat: -25.363, lng: 131.044 };

  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 4,
      center: myLatlng,
    }
  );

  const marker = new google.maps.Marker({
    position: myLatlng,
    map,
    title: "Click to zoom",
  });

  map.addListener("center_changed", () => {
    // 3 seconds after the center of the map has changed, pan back to the
    // marker.
    window.setTimeout(() => {
      map.panTo(marker.getPosition() as google.maps.LatLng);
    }, 3000);
  });

  marker.addListener("click", () => {
    map.setZoom(8);
    map.setCenter(marker.getPosition() as google.maps.LatLng);
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const myLatlng = { lat: -25.363, lng: 131.044 };
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: myLatlng,
  });
  const marker = new google.maps.Marker({
    position: myLatlng,
    map,
    title: "Click to zoom",
  });

  map.addListener("center_changed", () => {
    // 3 seconds after the center of the map has changed, pan back to the
    // marker.
    window.setTimeout(() => {
      map.panTo(marker.getPosition());
    }, 3000);
  });
  marker.addListener("click", () => {
    map.setZoom(8);
    map.setCenter(marker.getPosition());
  });
}

window.initMap = initMap;
Ver ejemplo

Probar la muestra

Sugerencia: Si intentas detectar un cambio en el viewport, asegúrate de usar el evento bounds_changed específico en lugar de los eventos zoom_changed y center_changed. Debido a que la API de Maps JavaScript activa estos últimos eventos de forma independiente, es posible que getBounds() no informe resultados útiles hasta después de que el viewport haya cambiado de manera autoritaria. Si deseas usar getBounds() después de un evento de este tipo, asegúrate de escuchar el evento bounds_changed.

Ejemplo: eventos de edición y arrastre de formas

Cuando se edita o arrastra una forma, se activa un evento cuando se completa la acción. Para obtener una lista de los eventos y algunos fragmentos de código, consulta Formas.

Ver el ejemplo (rectangle-event.html)

Cómo acceder a argumentos de eventos de la IU

Por lo general, los eventos de IU en la API de Maps JavaScript pasan un argumento de evento, al que puede acceder el objeto de escucha de eventos, y anotan el estado de la IU cuando se produce el evento. Por ejemplo, un evento 'click' de IU suele pasar un MouseEvent que contiene una propiedad latLng que denota la ubicación en la que se hizo clic en el mapa. Ten en cuenta que este comportamiento es único para los eventos de la IU; los cambios de estado de MVC no pasan argumentos en sus eventos.

Puedes acceder a los argumentos del evento dentro de un objeto de escucha de eventos de la misma manera en que accederías a las propiedades de un objeto. En el siguiente ejemplo, se agrega un objeto de escucha de eventos para el mapa y se crea un marcador cuando el usuario hace clic en la ubicación seleccionada del mapa.

TypeScript

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 4,
      center: { lat: -25.363882, lng: 131.044922 },
    }
  );

  map.addListener("click", (e) => {
    placeMarkerAndPanTo(e.latLng, map);
  });
}

function placeMarkerAndPanTo(latLng: google.maps.LatLng, map: google.maps.Map) {
  new google.maps.Marker({
    position: latLng,
    map: map,
  });
  map.panTo(latLng);
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: { lat: -25.363882, lng: 131.044922 },
  });

  map.addListener("click", (e) => {
    placeMarkerAndPanTo(e.latLng, map);
  });
}

function placeMarkerAndPanTo(latLng, map) {
  new google.maps.Marker({
    position: latLng,
    map: map,
  });
  map.panTo(latLng);
}

window.initMap = initMap;
Ver ejemplo

Probar la muestra

Cómo usar cierres en receptores de eventos

Cuando ejecutas un objeto de escucha de eventos, suele ser conveniente tener datos privados y persistentes adjuntos a un objeto. JavaScript no admite datos de instancias “privados”, pero sí admite cierres que permiten que las funciones internas accedan a variables externas. Los cierres son útiles dentro de los objetos de escucha de eventos para acceder a variables que normalmente no se adjuntan a los objetos en los que se producen eventos.

En el siguiente ejemplo, se usa un cierre de función en el objeto de escucha de eventos para asignar un mensaje secreto a un conjunto de marcadores. Si haces clic en cada marcador, se mostrará una parte del mensaje secreto que no está contenido dentro del marcador en sí.

TypeScript

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 4,
      center: { lat: -25.363882, lng: 131.044922 },
    }
  );

  const bounds: google.maps.LatLngBoundsLiteral = {
    north: -25.363882,
    south: -31.203405,
    east: 131.044922,
    west: 125.244141,
  };

  // Display the area between the location southWest and northEast.
  map.fitBounds(bounds);

  // Add 5 markers to map at random locations.
  // For each of these markers, give them a title with their index, and when
  // they are clicked they should open an infowindow with text from a secret
  // message.
  const secretMessages = ["This", "is", "the", "secret", "message"];
  const lngSpan = bounds.east - bounds.west;
  const latSpan = bounds.north - bounds.south;

  for (let i = 0; i < secretMessages.length; ++i) {
    const marker = new google.maps.Marker({
      position: {
        lat: bounds.south + latSpan * Math.random(),
        lng: bounds.west + lngSpan * Math.random(),
      },
      map: map,
    });

    attachSecretMessage(marker, secretMessages[i]);
  }
}

// Attaches an info window to a marker with the provided message. When the
// marker is clicked, the info window will open with the secret message.
function attachSecretMessage(
  marker: google.maps.Marker,
  secretMessage: string
) {
  const infowindow = new google.maps.InfoWindow({
    content: secretMessage,
  });

  marker.addListener("click", () => {
    infowindow.open(marker.get("map"), marker);
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: { lat: -25.363882, lng: 131.044922 },
  });
  const bounds = {
    north: -25.363882,
    south: -31.203405,
    east: 131.044922,
    west: 125.244141,
  };

  // Display the area between the location southWest and northEast.
  map.fitBounds(bounds);

  // Add 5 markers to map at random locations.
  // For each of these markers, give them a title with their index, and when
  // they are clicked they should open an infowindow with text from a secret
  // message.
  const secretMessages = ["This", "is", "the", "secret", "message"];
  const lngSpan = bounds.east - bounds.west;
  const latSpan = bounds.north - bounds.south;

  for (let i = 0; i < secretMessages.length; ++i) {
    const marker = new google.maps.Marker({
      position: {
        lat: bounds.south + latSpan * Math.random(),
        lng: bounds.west + lngSpan * Math.random(),
      },
      map: map,
    });

    attachSecretMessage(marker, secretMessages[i]);
  }
}

// Attaches an info window to a marker with the provided message. When the
// marker is clicked, the info window will open with the secret message.
function attachSecretMessage(marker, secretMessage) {
  const infowindow = new google.maps.InfoWindow({
    content: secretMessage,
  });

  marker.addListener("click", () => {
    infowindow.open(marker.get("map"), marker);
  });
}

window.initMap = initMap;
Ver ejemplo

Probar la muestra

Obtener y configurar propiedades dentro de los controladores de eventos

Ninguno de los eventos de cambio de estado de MVC que corresponden al sistema de eventos de la API de Maps JavaScript pasa argumentos cuando se activa el evento. (Los eventos de usuario pasan argumentos que pueden inspeccionarse). Si necesitas inspeccionar una propiedad en un cambio de estado de MVC, debes llamar explícitamente al método getProperty() apropiado en ese objeto. Esta inspección siempre recuperará el estado actual del objeto MVC, que puede no ser el estado cuando se activó el evento por primera vez.

Nota: Configurar de forma explícita una propiedad dentro de un controlador de eventos que responde a un cambio de estado de esa propiedad puede generar un comportamiento impredecible o no deseado. Por ejemplo, configurar una propiedad de ese tipo activará un evento nuevo y, si siempre configuras una propiedad dentro de este controlador de eventos, es posible que generes un bucle infinito.

En el siguiente ejemplo, configuramos un controlador de eventos para responder a los eventos de zoom mediante la aparición de una ventana de información que muestra ese nivel.

TypeScript

function initMap(): void {
  const originalMapCenter = new google.maps.LatLng(-25.363882, 131.044922);
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 4,
      center: originalMapCenter,
    }
  );

  const infowindow = new google.maps.InfoWindow({
    content: "Change the zoom level",
    position: originalMapCenter,
  });

  infowindow.open(map);

  map.addListener("zoom_changed", () => {
    infowindow.setContent("Zoom: " + map.getZoom()!);
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const originalMapCenter = new google.maps.LatLng(-25.363882, 131.044922);
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: originalMapCenter,
  });
  const infowindow = new google.maps.InfoWindow({
    content: "Change the zoom level",
    position: originalMapCenter,
  });

  infowindow.open(map);
  map.addListener("zoom_changed", () => {
    infowindow.setContent("Zoom: " + map.getZoom());
  });
}

window.initMap = initMap;
Ver ejemplo

Probar la muestra

Cómo escuchar eventos de DOM

El modelo de eventos de la API de Maps JavaScript crea y administra sus propios eventos personalizados. Sin embargo, el DOM (Document Object Model) del navegador también crea y despacha sus propios eventos, según el modelo de evento del navegador en uso. Si deseas capturar estos eventos y responder a ellos, la API de Maps JavaScript proporciona el método estático addDomListener() para detectar eventos de DOM y vincularse a ellos.

Este método de conveniencia tiene una firma, como se muestra a continuación:

addDomListener(instance:Object, eventName:string, handler:Function)

En el ejemplo anterior, instance puede ser cualquier elemento de DOM admitido por el navegador, incluidos los siguientes:

  • Miembros jerárquicos del DOM, como window o document.body.myform
  • Elementos con nombre, como document.getElementById("foo")

Ten en cuenta que addDomListener() pasa el evento indicado al navegador, el cual lo administra según el modelo de eventos de DOM del navegador. Sin embargo, casi todos los navegadores modernos admiten al menos el nivel de DOM 2. (Para obtener más información sobre los eventos de nivel de DOM, consulta la referencia de Niveles de DOM de Mozilla).

TypeScript

function initMap(): void {
  const mapDiv = document.getElementById("map") as HTMLElement;
  const map = new google.maps.Map(mapDiv, {
    zoom: 8,
    center: new google.maps.LatLng(-34.397, 150.644),
  });

  // We add a DOM event here to show an alert if the DIV containing the
  // map is clicked.
  google.maps.event.addDomListener(mapDiv, "click", () => {
    window.alert("Map was clicked!");
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const mapDiv = document.getElementById("map");
  const map = new google.maps.Map(mapDiv, {
    zoom: 8,
    center: new google.maps.LatLng(-34.397, 150.644),
  });

  // We add a DOM event here to show an alert if the DIV containing the
  // map is clicked.
  google.maps.event.addDomListener(mapDiv, "click", () => {
    window.alert("Map was clicked!");
  });
}

window.initMap = initMap;

HTML

<html>
  <head>
    <title>Listening to DOM 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
     with https://www.npmjs.com/package/@googlemaps/js-api-loader.
    -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
      defer
    ></script>
  </body>
</html>
Ver ejemplo

Probar la muestra

Si bien el código anterior es el código de la API de Maps JavaScript, el método addDomListener() se vincula al objeto window del navegador y permite que la API se comunique con objetos fuera del dominio normal de la API.

Cómo eliminar receptores de eventos

Para quitar un objeto de escucha de eventos específico, debe asignarse a una variable. Luego, puedes llamar a removeListener() y pasar el nombre de la variable a la que se asignó el objeto de escucha.

var listener1 = marker.addListener('click', aFunction);

google.maps.event.removeListener(listener1);

Para quitar todos los objetos de escucha de una instancia en particular, llama a clearInstanceListeners() y pasa el nombre de la instancia.

var listener1 = marker.addListener('click', aFunction);
var listener2 = marker.addListener('mouseover', bFunction);

// Remove listener1 and listener2 from marker instance.
google.maps.event.clearInstanceListeners(marker);

A fin de quitar todos los objetos de escucha de un tipo de evento específico para una instancia específica, llama a clearListeners() y pasa el nombre de la instancia y el nombre del evento.

marker.addListener('click', aFunction);
marker.addListener('click', bFunction);
marker.addListener('click', cFunction);

// Remove all click listeners from marker instance.
google.maps.event.clearListeners(marker, 'click');

Para obtener más información, consulta la documentación de referencia del espacio de nombres google.maps.event.

Detectar errores de autenticación

Si deseas detectar una falla de autenticación de manera programática (por ejemplo, para enviar una baliza automáticamente), puedes preparar una función de devolución de llamada. Si se define la siguiente función global, se la llamará cuando la autenticación falle. function gm_authFailure() { /* Code */ };