Eventos

Selecione a plataforma: Android iOS JavaScript

Esta página descreve os eventos da interface do usuário e eventos de erro que você pode detectar e tratar programaticamente.

Eventos da interface do usuário

O JavaScript no navegador funciona com base em eventos, o que significa que o JavaScript responde a interações gerando eventos e espera que um programa detecte os eventos interessantes. Há dois tipos de eventos:

  • Os eventos do usuário (como clique do mouse) são propagados do DOM para a API Maps JavaScript. Esses eventos são separados e diferentes dos eventos DOM padrão.
  • As notificações de alteração de estado de MVC refletem alterações em objetos da API Maps JavaScript e são nomeadas usando a convenção property_changed.

Cada objeto da API Maps JavaScript exporta vários eventos nomeados. Os programas interessados em determinados eventos vão registrar listeners de eventos JavaScript para esses eventos e executar o código quando esses eventos forem recebidos chamando addListener() para registrar os manipuladores de eventos no objeto.

O exemplo abaixo mostra quais eventos são acionados por google.maps.Map à medida que você interage com o mapa.

Para uma lista completa de eventos, consulte a Referência da API Maps JavaScript. Os eventos são listados em uma seção separada de cada objeto que contém eventos.

Eventos de interface de usuário

Alguns objetos da API Maps JavaScript foram projetados para responder a eventos do usuário, como cliques ou eventos do teclado. Alguns dos eventos do usuário que um objeto google.maps.Marker pode detectar são:

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

A lista completa está na classe Marcador. Esses eventos podem parecer eventos DOM padrão, mas fazem parte da API Maps JavaScript. Navegadores diferentes implementam modelos de evento DOM distintos e, por isso, a API Maps JavaScript fornece esses mecanismos para detectar e responder a eventos DOM sem precisar processar as diversas peculiaridades de vários navegadores. Normalmente, esses eventos também passam argumentos no evento anotando algum estado da IU (como a posição do mouse).

Alterações de estado de MVC

Normalmente, os objetos MVC têm um estado. Sempre que a propriedade de um objeto muda, a API Maps JavaScript dispara um evento que a propriedade mudou. Por exemplo, a API vai disparar um evento zoom_changed em um mapa quando o zoom do mapa mudar. Você pode interceptar essas mudanças de estado chamando addListener() para registrar manipuladores de eventos também no objeto.

Eventos de usuário e alterações de estado de MVC podem parecer semelhantes, mas normalmente são tratados de forma diferente no código. Eventos de MVC, por exemplo, não passam argumentos no evento. Inspecione a propriedade alterada em uma mudança de estado de MVC chamando o método getProperty apropriado naquele objeto.

Processar eventos

Para receber notificações de eventos, use o manipulador de eventos addListener(). Esse método assume um evento para detectar e uma função para chamar quando o evento especificado ocorre.

Exemplo: eventos de mapa e marcador

O código a seguir mistura eventos de usuário e de alteração de estado. Anexamos um manipulador de eventos a um marcador que altera o zoom do mapa quando clicado. Adicionamos também um manipulador de eventos ao mapa para monitorar mudanças na propriedade center e deslocar o mapa de volta ao marcador 3 segundos depois de receber o 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;
Exemplo

Testar amostra

Dica: para tentar detectar uma mudança na porta de visualização, não deixe de usar o evento bounds_changed específico em vez dos eventos envolvidos zoom_changed e center_changed. Como a API Maps JavaScript dispara esses eventos posteriores de maneira independente, getBounds() não pode relatar resultados úteis até que a janela de visualização tenha sido alterada de forma reconhecida. Para aplicar getBounds() após esse evento, detecte o evento bounds_changed.

Exemplo: eventos para editar e arrastar formas

Quando uma forma é editada ou arrastada, um evento é acionado quando a ação é concluída. Para uma lista dos eventos e de alguns snippets de código, consulte Formas.

Exemplo (rectangle-event.html)

Acessar argumentos em eventos de IU

Os eventos de IU na API Maps JavaScript normalmente transmitem um argumento de evento, que pode ser acessado pelo listener de eventos, observando o estado da IU quando o evento ocorreu. Por exemplo, um evento 'click' da interface do usuário normalmente passa um MouseEvent que contém uma propriedade latLng indicando o local clicado no mapa. Esse comportamento é exclusivo de eventos de IU. As alterações de estado de MVC não passam argumentos nos eventos.

Acesse os argumentos do evento em um ouvinte de eventos da mesma forma que acessa as propriedades de um objeto. O exemplo a seguir adiciona um listener de eventos ao mapa e, quando o usuário clica no mapa, cria um marcador na posição clicada.

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;
Exemplo

Testar amostra

Usar fechamentos em listeners de eventos

Ao executar um listener de eventos, muitas vezes é vantajoso ter dados privados e persistentes anexados a um objeto. O JavaScript não permite dados de instância "privados", mas aceita fechamentos, permitindo que funções internas acessem variáveis externas. Os fechamentos são úteis em listeners de eventos para acessar variáveis que normalmente não são anexadas aos objetos onde ocorrem os eventos.

O exemplo a seguir usa um fechamento de função no listener de eventos para atribuir uma mensagem secreta a um conjunto de marcadores. Ao clicar em um marcador, uma parte da mensagem secreta, que não está propriamente dentro do marcador, é revelada.

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;
Exemplo

Testar amostra

Obter e definir propriedades em manipuladores de eventos

Nenhum dos eventos de alteração de estado do MVC no sistema de eventos da API Maps JavaScript transmite argumentos quando o evento é acionado. (Eventos de usuário passam argumentos, que podem ser examinados.) Se precisar inspecionar uma propriedade em uma alteração de estado do MVC, chame explicitamente o método getProperty()apropriado no objeto em questão. Essa inspeção sempre recupera o estado atual do objeto do MVC, que pode não ser igual ao estado observado quando o evento foi disparado pela primeira vez.

Observação: a definição explícita de uma propriedade em um manipulador de eventos que responde a uma alteração de estado nessa propriedade pode causar um comportamento imprevisível e/ou indesejado. Por exemplo, a definição dessa propriedade aciona um novo evento. Se você sempre define uma propriedade no manipulador de eventos, o resultado pode ser um loop infinito.

No exemplo a seguir, configuramos um manipulador de eventos para responder a eventos de zoom mostrando uma janela de informações naquele nível.

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;
Exemplo

Testar amostra

Detectar eventos do DOM

O modelo de eventos da API Maps JavaScript cria e administra os próprios eventos personalizados. No entanto, o Document Object Model (DOM) no navegador também cria e despacha os próprios eventos, conforme o modelo de eventos específico do navegador usado. Se você quiser capturar e responder a esses eventos, a API Maps JavaScript oferece o método estático addDomListener() para ouvir e se vincular a eventos DOM.

Esse método de conveniência tem uma assinatura, como mostrado abaixo:

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

em que instance pode ser qualquer elemento do DOM permitido pelo navegador, incluindo:

  • Membros hierárquicos do DOM, como window ou document.body.myform
  • Elementos nomeados como document.getElementById("foo")

Observação: addDomListener() transmite o evento indicado ao navegador, que faz o processamento de acordo com o modelo de eventos DOM do navegador. No entanto, praticamente todos os navegadores mais recentes são compatíveis com o DOM nível 2, no mínimo. Para mais informações sobre eventos de nível do DOM, consulte a referência Níveis do DOM do 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.
      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&v=weekly"
      defer
    ></script>
  </body>
</html>
Exemplo

Testar amostra

Embora o código acima seja da API Maps JavaScript, o método do addDomListener() é vinculado ao objeto window do navegador e permite que a API se comunique com objetos fora do domínio normal da API.

Remover listeners de eventos

Só é possível remover listeners de eventos que estejam atribuídos a uma variável. Nesse caso, basta chamar removeListener(), transmitindo o nome da variável a que o listener foi atribuído.

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

google.maps.event.removeListener(listener1);

Para remover todos os listeners de uma instância específica, chame clearInstanceListeners(), transmitindo o nome da instância.

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

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

Se quiser remover todos os listeners de um tipo de evento específico de uma instância específica, chame clearListeners(), passando os nomes da instância e do 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 mais informações, consulte a documentação de referência do namespace google.maps.event.

Detectar erros de autenticação

Se quiser detectar uma falha de autenticação programaticamente (por exemplo, enviar um sensor automaticamente), você pode preparar uma função de callback. Se a função global a seguir estiver definida, ela vai ser chamada quando ocorrer um erro na autenticação. function gm_authFailure() { /* Code */ };