Eventi

Seleziona la piattaforma: Android iOS JavaScript

Questa pagina descrive gli eventi dell'interfaccia utente e quelli di errore che puoi ascoltare e gestire in modo programmatico.

Eventi dell'interfaccia utente

JavaScript all'interno del browser è basato su eventi, il che significa che JavaScript risponde alle interazioni generando eventi e prevede che un programma ascolta eventi interessanti. Esistono due tipi di eventi:

  • Gli eventi utente (come gli eventi del mouse "clic") vengono propagati dal DOM all'API Maps JavaScript. Questi eventi sono separati e distinti dagli eventi DOM standard.
  • Le notifiche di modifica dello stato MVC riflettono le modifiche negli oggetti dell'API Maps JavaScript e vengono denominate utilizzando una convenzione property_changed.

Ogni oggetto dell'API Maps JavaScript esporta una serie di eventi denominati. I programmi interessati a determinati eventi registrano i Listener di eventi JavaScript per questi eventi ed eseguono il codice quando questi eventi vengono ricevuti chiamando addListener() per registrare i gestori di eventi sull'oggetto.

Il seguente esempio mostra quali eventi vengono attivati da google.maps.Map quando interagisci con la mappa.

Per un elenco completo degli eventi, consulta la documentazione di riferimento dell'API JavaScript di Maps. Gli eventi vengono elencati in una sezione separata per ogni oggetto che contiene eventi.

Eventi UI

Alcuni oggetti all'interno dell'API Maps JavaScript sono progettati per rispondere a eventi utente come eventi del mouse o della tastiera. Ad esempio, questi sono alcuni degli eventi utente che un oggetto google.maps.marker.AdvancedMarkerElement può ascoltare:

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

Per l'elenco completo, consulta la classe AdvancedMarkerElement. Questi eventi possono sembrare eventi DOM standard, ma in realtà fanno parte dell'API Maps JavaScript. Poiché browser diversi implementano modelli di eventi DOM diversi, l'API Maps JavaScript fornisce questi meccanismi per ascoltare gli eventi DOM e rispondere senza dover gestire le varie peculiarità tra browser. In genere questi eventi passano anche gli argomenti all'interno dell'evento, indicando alcuni stati dell'interfaccia utente (come la posizione del mouse).

Cambiamenti di stato MVC

Gli oggetti MVC di solito contengono uno stato. Ogni volta che la proprietà di un oggetto cambia, l'API Maps JavaScript attiva un evento che la proprietà è stata modificata. Ad esempio, l'API attiva un evento zoom_changed su una mappa quando cambia il livello di zoom della mappa. Puoi intercettare queste modifiche di stato chiamando addListener() per registrare anche i gestori di eventi nell'oggetto.

Gli eventi utente e le modifiche dello stato della MVC possono sembrare simili, ma in genere vuoi trattarli in modo diverso nel codice. Gli eventi MVC, ad esempio, non passano gli argomenti al loro interno. Ti consigliamo di esaminare la proprietà modificata in seguito a una modifica di stato MVC chiamando il metodo getProperty appropriato sull'oggetto in questione.

Gestire gli eventi

Per registrarti per le notifiche degli eventi, utilizza il gestore di eventi addListener(). Questo metodo richiede un evento da rimanere in ascolto e una funzione da chiamare quando si verifica l'evento specificato.

Esempio: eventi mappa ed indicatori

Il codice seguente combina eventi utente con eventi di modifica dello stato. Alleghiamo un gestore di eventi a un indicatore che ingrandisce la mappa quando l'utente fa clic. Aggiungiamo anche un gestore di eventi alla mappa per le modifiche apportate alla proprietà center e portiamo la mappa sull'indicatore dopo 3 secondi dalla ricezione dell'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();
Visualizza esempio

Prova Sample

Suggerimento: se stai cercando di rilevare una modifica nell'area visibile, assicurati di utilizzare l'evento bounds_changed specifico anziché gli eventi zoom_changed e center_changed che lo compongono. Poiché l'API Maps JavaScript attiva questi ultimi eventi in modo indipendente, getBounds() potrebbe non segnalare risultati utili fino a quando l'area visibile non è stata modificata in modo autorevole. Se vuoi getBounds() dopo un evento di questo tipo, assicurati di ascoltare l'evento bounds_changed.

Esempio: eventi di modifica e trascinamento delle forme

Quando una forma viene modificata o trascinata, viene attivato un evento al completamento dell'azione. Per un elenco degli eventi e di alcuni snippet di codice, consulta Forme.

Visualizza esempio (rettangolare-evento.html)

Argomenti di accesso negli eventi UI

Gli eventi UI all'interno dell'API Maps JavaScript in genere passano un argomento evento, a cui il listener di eventi può accedere, che indica lo stato dell'interfaccia utente quando si è verificato l'evento. Ad esempio, un evento 'click' dell'interfaccia utente di solito trasmette un MouseEvent contenente una proprietà latLng che indica la posizione selezionata sulla mappa. Tieni presente che questo comportamento è univoco per gli eventi dell'interfaccia utente; le modifiche dello stato MVC non passano gli argomenti nei loro eventi.

Puoi accedere agli argomenti dell'evento all'interno di un listener di eventi come faresti per accedere alle proprietà di un oggetto. Nell'esempio seguente viene aggiunto un listener di eventi per la mappa e viene creato un indicatore quando l'utente fa clic sulla mappa nel punto selezionato.

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();
Visualizza esempio

Prova Sample

Utilizzo delle chiusure nei listener di eventi

Durante l'esecuzione di un listener di eventi, spesso è vantaggioso collegare dati privati e permanenti a un oggetto. JavaScript non supporta i dati delle istanze "private", ma supporta le chiusure, che consentono alle funzioni interne di accedere alle variabili esterne. Le chiusure sono utili all'interno dei listener di eventi per accedere a variabili non normalmente collegate agli oggetti su cui si verificano eventi.

L'esempio seguente utilizza una chiusura di funzione nel listener di eventi per assegnare un messaggio secret a un insieme di indicatori. Se fai clic su ciascun indicatore, verrà mostrata una parte del messaggio del secret, che non è contenuta all'interno dell'indicatore stesso.

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();
Visualizza esempio

Prova Sample

Recupero e impostazione di proprietà all'interno dei gestori di eventi

Nessuno degli eventi di modifica dello stato MVC nel sistema di eventi dell'API Maps JavaScript supera gli argomenti quando l'evento viene attivato. Gli eventi utente passano gli argomenti che possono essere ispezionati. Se devi ispezionare una proprietà in caso di modifica dello stato MVC, devi chiamare esplicitamente il metodo getProperty() appropriato per l'oggetto in questione. Questa ispezione recupererà sempre lo stato attuale dell'oggetto MVC, che potrebbe non corrispondere a quello della prima attivazione dell'evento.

Nota: l'impostazione esplicita di una proprietà all'interno di un gestore di eventi che risponde a una modifica dello stato di quella particolare proprietà può produrre comportamenti imprevedibili e/o indesiderati. L'impostazione di una proprietà di questo tipo attiverà un nuovo evento, ad esempio. Se imposti sempre una proprietà all'interno di questo gestore di eventi, potresti creare un loop infinito.

Nell'esempio riportato di seguito, impostiamo un gestore di eventi per rispondere agli eventi di zoom visualizzando una finestra informativa che mostra quel livello.

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();
Visualizza esempio

Prova Sample

Ascoltare gli eventi DOM

Il modello di eventi dell'API Maps JavaScript crea e gestisce i propri eventi personalizzati. Tuttavia, il DOM (Document Object Model) all'interno del browser crea e invia anche i propri eventi, in base al particolare modello di eventi del browser in uso. Se vuoi acquisire e rispondere a questi eventi, l'API Maps JavaScript fornisce il metodo statico addDomListener() per ascoltare e associare gli eventi DOM.

Questo metodo di convenienza ha una firma, come mostrato di seguito:

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

dove instance può essere qualsiasi elemento DOM supportato dal browser, tra cui:

  • Membri gerarchici del DOM, come window o document.body.myform
  • Elementi con nome, come document.getElementById("foo")

Tieni presente che addDomListener() passa l'evento indicato al browser, che lo gestisce in base al modello di eventi DOM del browser. Tuttavia, quasi tutti i browser moderni supportano almeno il livello DOM 2. Per ulteriori informazioni sugli eventi a livello di DOM, consulta la documentazione sui livelli di Mozilla DOM.

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>
Visualizza esempio

Prova Sample

Sebbene il codice riportato sopra sia il codice dell'API Maps JavaScript, il metodo addDomListener() si associa all'oggetto window del browser e consente all'API di comunicare con oggetti al di fuori del normale dominio dell'API.

Rimuovi listener di eventi

Per rimuovere un listener di eventi specifico, deve essere stato assegnato a una variabile. Puoi quindi chiamare removeListener(), passando il nome della variabile a cui è stato assegnato il listener.

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

google.maps.event.removeListener(listener1);

Per rimuovere tutti i listener da una determinata istanza, chiama clearInstanceListeners(), trasmettendo il nome dell'istanza.

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

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

Per rimuovere tutti i listener per un tipo di evento specifico per un'istanza specifica, chiama clearListeners(), trasmettendo il nome dell'istanza e dell'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');

Per saperne di più, consulta la documentazione di riferimento per lo spazio dei nomi google.maps.event.

Ascoltare gli errori di autenticazione

Se vuoi rilevare in modo programmatico un errore di autenticazione (ad esempio, inviare automaticamente un beacon), puoi preparare una funzione di callback. Se viene definita la seguente funzione globale, verrà richiamata quando l'autenticazione non va a buon fine. function gm_authFailure() { /* Code */ };