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 determinadas ações vão registrar listeners de eventos JavaScript e executar o código quando esses eventos forem recebidos, chamando addListener() para registrar os manipuladores de eventos no objeto.

Confira no exemplo abaixo quais eventos a classe google.maps.Map aciona quando você interage com o mapa.

Para ver 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 da interface

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

  • 'click'
  • 'drag'
  • 'dragend'
  • 'dragstart'
  • 'gmp-click'

A lista completa está na classe AdvancedMarkerElement. 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 interface (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 com a propriedade que 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. Para inspecionar a propriedade alterada em uma mudança de estado de MVC, chame o método getProperty apropriado no objeto em questão.

Processar eventos

Para receber notificações, 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

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary;
  const { AdvancedMarkerElement } = await google.maps.importLibrary("marker") as google.maps.MarkerLibrary;

  const myLatlng = { lat: -25.363, lng: 131.044 };

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

  const marker = new google.maps.marker.AdvancedMarkerElement({
    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.position as google.maps.LatLng);
    }, 3000);
  });

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

initMap();

JavaScript

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps");
  const { AdvancedMarkerElement } = await google.maps.importLibrary("marker");
  const myLatlng = { lat: -25.363, lng: 131.044 };
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: myLatlng,
    mapId: "DEMO_MAP_ID",
  });
  const marker = new google.maps.marker.AdvancedMarkerElement({
    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.position);
    }, 3000);
  });
  marker.addListener("click", () => {
    map.setZoom(8);
    map.setCenter(marker.position);
  });
}

initMap();
Exemplo

Testar amostra

Dica: para tentar detectar uma mudança na janela de visualização, use o evento bounds_changed específico em vez dos eventos zoom_changed e center_changed envolvidos. 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.

Veja um exemplo (rectangle-event.html)

Acessar argumentos nos eventos de interface

Os eventos de interface na API Maps JavaScript normalmente transmitem um argumento de evento, que pode ser acessado pelo listener de eventos, observando o estado da interface 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 interface. 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

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary;
  const { AdvancedMarkerElement, PinElement } = await google.maps.importLibrary("marker") as google.maps.MarkerLibrary;

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

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

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

initMap();

JavaScript

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps");
  const { AdvancedMarkerElement, PinElement } = await google.maps.importLibrary(
    "marker",
  );
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: { lat: -25.363882, lng: 131.044922 },
    mapId: "DEMO_MAP_ID",
  });

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

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

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

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary;
  const { AdvancedMarkerElement } = await google.maps.importLibrary("marker") as google.maps.MarkerLibrary;

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

  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.AdvancedMarkerElement({
      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.AdvancedMarkerElement,
  secretMessage: string
) {
  const infowindow = new google.maps.InfoWindow({
    content: secretMessage,
  });

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

initMap();

JavaScript

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps");
  const { AdvancedMarkerElement } = await google.maps.importLibrary("marker");
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: { lat: -25.363882, lng: 131.044922 },
    mapId: "DEMO_MAP_ID",
  });
  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.AdvancedMarkerElement({
      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.map, marker);
  });
}

initMap();
Exemplo

Testar amostra

Receber e definir propriedades em manipuladores de eventos

Nenhum evento de mudança de estado de 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

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary;

  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()!);
  });
}

initMap();

JavaScript

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps");
  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());
  });
}

initMap();
Exemplo

Testar amostra

Ouvir 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

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary;

  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!");
  });
}

initMap();

JavaScript

async function initMap() {
  // Request needed libraries.
  const { Map } = await google.maps.importLibrary("maps");
  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!");
  });
}

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>

    <!-- prettier-ignore -->
    <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
        ({key: "AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg", v: "weekly"});</script>
  </body>
</html>
Exemplo

Testar amostra

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

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.

Ouvir erros de autenticação

Se quiser detectar de maneira programática uma falha de autenticação (por exemplo, para enviar um beacon automaticamente), prepare uma função de callback. Se a função global a seguir estiver definida, ela será chamada quando ocorrer um erro na autenticação. function gm_authFailure() { /* Code */ };