Eventi

Seleziona la piattaforma: Android iOS JavaScript

Questa pagina descrive gli eventi dell'interfaccia utente e gli eventi di errore che puoi ascoltare e gestire tramite programmazione.

Eventi dell'interfaccia utente

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

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

Ogni oggetto dell'API JavaScript di Maps esporta una serie di eventi denominati. I programmi interessati a determinati eventi registreranno event listener JavaScript per questi eventi ed eseguiranno il codice quando vengono ricevuti chiamando addListener() per registrare i gestori di eventi nell'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 il riferimento all'API Maps JavaScript. Gli eventi sono elencati in una sezione separata per ogni oggetto che li contiene.

Eventi UI

Alcuni oggetti all'interno dell'API JavaScript di Maps sono progettati per rispondere agli eventi utente, come quelli del mouse o della tastiera. Ad esempio, di seguito sono riportati 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 fanno parte dell'API Maps JavaScript. Poiché browser diversi implementano modelli di eventi DOM diversi, l'API JavaScript di Maps fornisce questi meccanismi per ascoltare e rispondere agli eventi DOM senza dover gestire le varie peculiarità cross-browser. In genere, questi eventi trasmettono anche argomenti all'interno dell'evento che indicano alcuni stati dell'interfaccia utente (ad esempio la posizione del mouse).

Modifiche allo stato MVC

Gli oggetti MVC in genere contengono uno stato. Ogni volta che la proprietà di un oggetto cambia, l'API JavaScript di Maps attiva un evento che indica 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 MVC possono sembrare simili, ma in genere è preferibile gestirli in modo diverso nel codice. Gli eventi MVC, ad esempio, non passano gli argomenti all'interno dell'evento. Ti consigliamo di ispezionare la proprietà che è stata modificata in seguito a una modifica dello stato MVC chiamando il metodo getProperty appropriato sull'oggetto.

Gestire gli eventi

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

Esempio: eventi mappa e indicatori

Il seguente codice mescola gli eventi utente con gli eventi di modifica dello stato. Associamo un gestore di eventi a un indicatore che aumenta lo zoom della mappa quando viene fatto clic. Aggiungiamo inoltre un gestore di eventi alla mappa per le modifiche alla proprietà center e ripianifichiamo la mappa sull'indicatore dopo 3 secondi alla 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 nel viewport, assicurati di utilizzare l'evento bounds_changed specifico anziché gli eventi costituenti zoom_changed e center_changed. Poiché l'API Maps JavaScript attiva questi ultimi eventi in modo indipendente, getBounds() potrebbe non generare risultati utili fino a quando la visualizzazione della pagina non è stata modificata in modo autorevole. Se vuoi getBounds() dopo un evento di questo tipo, assicurati di ascoltare invece l'evento bounds_changed.

Esempio: eventi di modifica e trascinamento delle forme

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

Visualizza l'esempio (rectangle-event.html)

Accedere agli argomenti negli eventi UI

In genere, gli eventi UI all'interno dell'API JavaScript di Maps passano un argomento evento, a cui può accedere l'ascoltatore di eventi, che indica lo stato dell'interfaccia utente al verificarsi dell'evento. Ad esempio, un evento 'click' dell'interfaccia utente in genere passa un MouseEvent contenente una proprietà latLng che indica la posizione su cui è stato fatto clic sulla mappa. Tieni presente che questo comportamento è esclusivo degli eventi UI. Le modifiche dello stato MVC non passano gli argomenti nei relativi eventi.

Puoi accedere agli argomenti dell'evento all'interno di un gestore eventi nello stesso modo in cui accederesti alle proprietà di un oggetto. Il seguente esempio aggiunge un listener di eventi per la mappa e crea un indicatore quando l'utente fa clic sulla mappa nella posizione selezionata.

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

Utilizzare le chiusure nei listener di eventi

Quando esegui un gestore di eventi, spesso è vantaggioso avere dati sia privati che permanenti associati a un oggetto. JavaScript non supporta i dati di istanze "private", ma supporta le chiusure che consentono alle funzioni interne di accedere alle variabili esterne. Le chiusure sono utili all'interno degli ascoltatori di eventi per accedere alle variabili non normalmente associate agli oggetti su cui si verificano gli eventi.

L'esempio seguente utilizza una chiusura di funzione nell'ascoltatore di eventi per assegnare un messaggio segreto a un insieme di indicatori. Se fai clic su ogni indicatore, viene rivelata una parte del messaggio segreto, che non è contenuta nell'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

Ottenere e impostare le proprietà all'interno dei gestori di eventi

Nessuno degli eventi di modifica dello stato MVC nel sistema di eventi dell'API Maps JavaScript passa argomenti al momento dell'attivazione. Gli eventi utente infatti passano argomenti che possono essere ispezionati. Se devi ispezionare una proprietà in una modifica dello stato MVC, devi chiamare esplicitamente il metodo getProperty() appropriato su quell'oggetto. Questa indagine recupererà sempre lo stato corrente dell'oggetto MVC, che potrebbe non essere lo stato al momento dell'attivazione dell'evento.

Nota: l'impostazione esplicita di una proprietà all'interno di un gestore eventi che risponde a una modifica dello stato di quella determinata proprietà può produrre un comportamento imprevedibile e/o indesiderato. L'impostazione di una proprietà di questo tipo attiverà un nuovo evento, ad esempio, e se imposti sempre una proprietà all'interno di questo gestore di eventi, potresti finire per creare un loop infinito.

Nell'esempio seguente, abbiamo configurato un gestore eventi per rispondere agli eventi di zoom visualizzando una finestra informativa che mostra il 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

Ascolta gli eventi DOM

Il modello di evento 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 associarsi agli eventi DOM.

Questo metodo di utilità 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, ad esempio window o document.body.myform
  • Elementi denominati come document.getElementById("foo")

Tieni presente che addDomListener() passa l'evento indicato al browser, che lo gestisce in base al modello di evento 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 di riferimento Livelli DOM di 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>

    <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 JavaScript di Maps, il metodo addDomListener() si lega all'oggetto window del browser e consente all'API di comunicare con oggetti esterni al normale dominio dell'API.

Rimuovere i listener di eventi

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

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

google.maps.event.removeListener(listener1);

Per rimuovere tutti gli ascoltatori da una determinata istanza, chiama clearInstanceListeners(), passando 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 gli ascoltatori per un tipo di evento specifico per un'istanza specifica, chiama clearListeners() passando il nome dell'istanza e il nome 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 il spazio dei nomi google.maps.event.

Ascolta gli errori di autenticazione

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