Zdarzenia

Wybierz platformę: Android iOS JavaScript

Na tej stronie opisujemy zdarzenia interfejsu i zdarzenia błędów, których możesz wykrywać i obsługiwać w sposób zautomatyzowany.

Zdarzenia w interfejsie

Kod JavaScript w przeglądarce jest sterowany zdarzeniami, co oznacza, że reaguje na interakcje, generując zdarzenia, i oczekuje, że program nasłuchuje interesujących zdarzeń. Istnieją 2 rodzaje zdarzeń:

  • Zdarzenia użytkownika (takie jak zdarzenia myszy „kliknięcie”) są propagowane z modelu DOM do interfejsu Maps JavaScript API. Zdarzenia te są niezależne od standardowych zdarzeń DOM.
  • Powiadomienia o zmianie stanu MVC odzwierciedlają zmiany w obiektach Maps JavaScript API i są nazywane zgodnie z konwencją property_changed.

Każdy obiekt Maps JavaScript API eksportuje pewną liczbę nazwanych zdarzeń. Programy zainteresowane określonymi zdarzeniami będą rejestrować dla nich detektory JavaScriptu i uruchamiać kod po ich otrzymaniu, wywołując addListener() w celu zarejestrowania modułów obsługi zdarzeń w obiekcie.

Poniższy przykład pokazuje, które zdarzenia są wywoływane przez interfejs google.maps.Map podczas interakcji z mapą.

Pełną listę zdarzeń znajdziesz w dokumentacji interfejsu Maps JavaScript API. Zdarzenia są wymienione w osobnej sekcji dotyczącej każdego obiektu zawierającego zdarzenia.

Zdarzenia interfejsu

Niektóre obiekty interfejsu Maps JavaScript API są zaprojektowane tak, aby odpowiadały na zdarzenia użytkownika, takie jak zdarzenia myszy lub klawiatury. Obiekt google.maps.marker.AdvancedMarkerElement może na przykład nasłuchiwać na przykład niektórych zdarzeń użytkownika:

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

Pełną listę znajdziesz w klasie AdvancedMarkerElement. Te zdarzenia mogą wyglądać jak standardowe zdarzenia DOM, ale w rzeczywistości są częścią interfejsu Maps JavaScript API. Różne przeglądarki implementują różne modele zdarzeń DOM, dlatego interfejs Maps JavaScript API udostępnia te mechanizmy nasłuchiwania zdarzeń DOM i reagowania na nie bez konieczności obsługi różnych specyfiki działania różnych przeglądarek. Zdarzenia te zwykle przekazują też argumenty w obrębie zdarzenia, zwracając uwagę na stan interfejsu użytkownika (np. pozycję kursora myszy).

Zmiany stanu MVC

Obiekty MVC zwykle zawierają stan. Po każdej zmianie właściwości obiektu interfejs Maps JavaScript API uruchomi zdarzenie związane ze zmianą właściwości. Na przykład interfejs API wywoła na mapie zdarzenie zoom_changed, gdy zmieni się jej poziom powiększenia. Możesz przechwycić te zmiany stanu, wywołując addListener(), aby zarejestrować moduły obsługi zdarzeń także w obiekcie.

Zdarzenia użytkownika i zmiany stanu MVC mogą wyglądać podobnie, ale najlepiej traktować je w kodzie inaczej. Na przykład zdarzenia MVC nie przekazują argumentów w ramach zdarzenia. Aby sprawdzić właściwość, która zmieniła się po zmianie stanu MVC, wywołaj w tym obiekcie odpowiednią metodę getProperty.

Obsługa zdarzeń

Aby zarejestrować się, aby otrzymywać powiadomienia o zdarzeniach, użyj modułu obsługi zdarzeń addListener(). Ta metoda pobiera nasłuchiwane zdarzenie i funkcję, która wywołuje ją po wystąpieniu określonego zdarzenia.

Przykład: zdarzenia związane z mapą i znacznikami

Ten kod łączy zdarzenia użytkownika ze zdarzeniami zmiany stanu. Do znacznika dołączamy moduł obsługi zdarzeń, który po kliknięciu powiększa mapę. Do mapy dodajemy też moduł obsługi zdarzeń w przypadku zmian we właściwości center i po 3 sekundach od otrzymania zdarzenia center_changed przesuwamy mapę z powrotem do znacznika:

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();
Zobacz przykład

Wypróbuj fragment

Wskazówka: jeśli chcesz wykryć zmianę widocznego obszaru, użyj konkretnego zdarzenia bounds_changed, a nie składowych zdarzeń zoom_changed i center_changed. Interfejs Maps JavaScript API uruchamia te ostatnie zdarzenia niezależnie, dlatego funkcja getBounds() może zgłaszać przydatne wyniki dopiero po autorytatywnej zmianie widocznego obszaru. Jeśli po takim zdarzeniu chcesz getBounds(), nasłuchuj zdarzenia bounds_changed.

Przykład: zdarzenia edytowania i przeciągania kształtów

Edytowanie lub przeciąganie kształtu powoduje wywołanie zdarzenia po zakończeniu działania. Listę zdarzeń i niektóre fragmenty kodu znajdziesz w sekcji Kształty.

Zobacz przykład (rectangle-event.html)

Uzyskiwanie dostępu do argumentów w zdarzeniach interfejsu

Zdarzenia interfejsu dostępne w interfejsie Maps JavaScript API zwykle przekazują argument zdarzenia, do którego detektor zdarzeń ma dostęp, wskazując stan interfejsu w momencie wystąpienia zdarzenia. Na przykład zdarzenie 'click' w interfejsie zwykle przekazuje obiekt MouseEvent zawierający właściwość latLng oznaczającą klikniętą lokalizację na mapie. To zachowanie występuje tylko w przypadku zdarzeń interfejsu. Zmiany stanu MVC nie przekazują argumentów w zdarzeniach.

Dostęp do argumentów zdarzenia w odbiorniku zdarzeń możesz uzyskać w taki sam sposób jak do właściwości obiektu. Poniższy przykład pokazuje dodanie detektora zdarzeń do mapy i utworzenie znacznika, gdy użytkownik kliknie mapę w klikniętej lokalizacji.

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();
Zobacz przykład

Wypróbuj fragment

Używanie zamknięcia w detektorach zdarzeń

Podczas wykonywania detektora zdarzeń często dobrze jest przyłączyć do obiektu zarówno prywatne, jak i trwałe dane. JavaScript nie obsługuje danych instancji „prywatnych”, ale obsługuje zamknięcia, które umożliwiają funkcjom wewnętrznym dostęp do zmiennych zewnętrznych. Zamknięcie przydaje się w detektorach zdarzeń i pozwala uzyskać dostęp do zmiennych, które nie są normalnie dołączone do obiektów, w których występują zdarzenia.

W tym przykładzie użyto zamknięcia funkcji w odbiorniku, aby przypisać tajną wiadomość do zestawu znaczników. Kliknięcie każdego znacznika spowoduje wyświetlenie części tajnej wiadomości, której nie ma w samym znacznika.

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();
Zobacz przykład

Wypróbuj fragment

Pobieranie i ustawianie właściwości w modułach obsługi zdarzeń

Żadne ze zdarzeń zmiany stanu MVC w systemie zdarzeń interfejsu Maps JavaScript API nie przekazuje argumentów po ich wywołaniu. Zdarzenia użytkownika przekazują argumenty, które można zbadać. Jeśli chcesz sprawdzić właściwość w przypadku zmiany stanu MVC, musisz wyraźnie wywołać w tym obiekcie odpowiednią metodę getProperty(). Ta kontrola zawsze pobiera bieżący stan obiektu MVC, który może nie być tym, który był w momencie pierwszego uruchomienia zdarzenia.

Uwaga: ustawienie właściwości w module obsługi zdarzeń, która reaguje na zmianę stanu tej konkretnej usługi, może spowodować nieprzewidywalne lub niepożądane zachowanie. Ustawienie takiej właściwości będzie wywoływać na przykład nowe zdarzenie, a jeśli zawsze ustawisz właściwość w tym module obsługi zdarzeń, może to doprowadzić do utworzenia pętli nieskończonej.

W przykładzie poniżej skonfigurowaliśmy moduł obsługi zdarzeń, który będzie reagować na zdarzenia powiększenia poprzez wyświetlenie okna informacyjnego wyświetlającego dany poziom.

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();
Zobacz przykład

Wypróbuj fragment

Odbiór zdarzeń DOM

Model zdarzenia Maps JavaScript API tworzy własne zdarzenia niestandardowe i nimi zarządza. Jednak DOM w przeglądarce tworzy i wysyła też własne zdarzenia zgodnie z używanym modelem zdarzeń przeglądarki. Jeśli chcesz przechwytywać te zdarzenia i reagować na nie, interfejs Maps JavaScript API udostępnia statyczną metodę addDomListener(), która nasłuchuje zdarzeń DOM i tworzy z nimi powiązania.

Ta wygodna metoda ma podpis, jak pokazano poniżej:

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

gdzie instance może być dowolnym elementem DOM obsługiwanym przez przeglądarkę, w tym:

  • Hierarchiczne elementy DOM, np. window lub document.body.myform
  • elementy nazwane, np. document.getElementById("foo");

Pamiętaj, że interfejs addDomListener() przekazuje wskazane zdarzenie do przeglądarki, która obsługuje je zgodnie z jej modelem zdarzeń DOM. Jednak niemal wszystkie nowoczesne przeglądarki obsługują co najmniej DOM poziomu 2. Więcej informacji o zdarzeniach na poziomie DOM znajdziesz w dokumentacji Mozilla DOM Levels.

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>
Zobacz przykład

Wypróbuj fragment

Chociaż powyższy kod to kod Maps JavaScript API, metoda addDomListener() wiąże się z obiektem window przeglądarki i umożliwia interfejsowi API komunikację z obiektami spoza normalnej domeny interfejsu API.

Usuń detektory zdarzeń

Aby usunąć określony detektor zdarzeń, musisz go przypisać do zmiennej. Następnie możesz wywołać removeListener(), przekazując nazwę zmiennej, do której został przypisany detektor.

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

google.maps.event.removeListener(listener1);

Aby usunąć z konkretnej instancji wszystkie detektory, wywołaj clearInstanceListeners(), przekazując nazwę instancji.

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

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

Aby w przypadku konkretnej instancji usunąć wszystkie detektory danego typu zdarzenia, wywołaj clearListeners(), przekazując nazwę instancji i nazwę zdarzenia.

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');

Więcej informacji znajdziesz w dokumentacji referencyjnej przestrzeni nazw google.maps.event.

Wykrywaj błędy uwierzytelniania

Jeśli chcesz automatycznie wykrywać błąd uwierzytelniania (np. automatycznie wysyłać beacon), możesz przygotować funkcję wywołania zwrotnego. Jeśli zdefiniowana jest ta funkcja globalna, zostanie ona wywołana po niepowodzeniu uwierzytelniania. function gm_authFailure() { /* Code */ };