Na tej stronie opisujemy zdarzenia interfejsu użytkownika i zdarzenia błędu, które możesz przechwytywać i obsługiwać programowo.
Zdarzenia interfejsu użytkownika
Kod JavaScript w przeglądarce jest sterowany zdarzeniami, co oznacza, że reaguje na interakcje przez generowanie zdarzeń i oczekuje, że program będzie słuchać interesujących zdarzeń. Istnieją 2 rodzaje zdarzeń:
- Zdarzenia użytkownika (np. zdarzenia myszy „kliknięcie”) są propagowane z DOM do Maps JavaScript API. Te zdarzenia są odrębne i różne od standardowych zdarzeń DOM.
- Powiadomienia o zmianie stanu MVC odzwierciedlają zmiany w obiektach interfejsu Maps JavaScript API i są nazywane zgodnie z konwencją
property_changed
.
Każdy obiekt Maps JavaScript API eksportuje określoną liczbę nazwanych zdarzeń.
Programy zainteresowane określonymi zdarzeniami rejestrują dla nich detektory zdarzeń w JavaScriptie i wykonują kod po otrzymaniu tych zdarzeń, wywołując addListener()
, aby zarejestrować moduły obsługi zdarzeń w obiekcie.
Ten przykładowy kod pokazuje, które zdarzenia są wywoływane przez google.maps.Map
podczas interakcji z mapą.
Pełną listę zdarzeń znajdziesz w dokumentacji interfejsu Maps JavaScript API. Zdarzenia są wymienione w osobnej sekcji dla każdego obiektu zawierającego zdarzenia.
Zdarzenia w interfejsie
Niektóre obiekty w interfejsie Maps JavaScript API są zaprojektowane tak, aby reagować na zdarzenia użytkownika, takie jak zdarzenia myszy lub klawiatury. Oto przykłady zdarzeń użytkownika, na które może reagować obiekt google.maps.marker.AdvancedMarkerElement
:
'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. Ponieważ różne przeglądarki implementują różne modele zdarzeń DOM, interfejs Maps JavaScript API udostępnia mechanizmy, które umożliwiają nasłuchiwanie zdarzeń DOM i na nie reagowanie bez konieczności obsługi różnych specyfikiczności w różnych przeglądarkach. Zdarzenia te przekazują też zwykle argumenty w ramach zdarzenia, wskazując stan interfejsu użytkownika (np. pozycję kursora).
Zmiany stanu MVC
Obiekty MVC zwykle zawierają stan. Za każdym razem, gdy zmieni się atrybut obiektu, Maps JavaScript API wywoła zdarzenie zmiany tego atrybutu.
Na przykład interfejs API uruchamia zdarzenie zoom_changed
na mapie, gdy zmienia się poziom jej powiększenia. Możesz przechwycić te zmiany stanu, wywołując funkcję addListener()
, aby zarejestrować też moduły obsługi zdarzeń dla tego obiektu.
Zdarzenia użytkownika i zmiany stanu MVC mogą wyglądać podobnie, ale zazwyczaj warto traktować je w kodzie inaczej. Na przykład zdarzenia MVC nie przekazują argumentów w ramach zdarzenia. Aby sprawdzić, która właściwość zmieniła się po zmianie stanu MVC, wywołaj odpowiednią metodę getProperty
tego obiektu.
Obsługa zdarzeń
Aby zarejestrować się na powiadomienia o zdarzeniach, użyj modułu obsługi zdarzeń addListener()
. Ta metoda przyjmuje zdarzenie do nasłuchiwania i funkcję do wywołania po wystąpieniu określonego zdarzenia.
Przykład: zdarzenia mapy i znaczników
Podany niżej kod łączy zdarzenia użytkownika ze zdarzeniami zmiany stanu. Do znacznika, który po kliknięciu powiększa mapę, dołączamy moduł obsługi zdarzenia. Dodajemy też do mapy moduł obsługi zdarzeń dla zmian 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();
Wypróbuj próbkę
Wskazówka: jeśli chcesz wykryć zmianę w widoku, użyj konkretnego zdarzenia bounds_changed
, a nie zdarzeń składowych zoom_changed
i center_changed
. Ponieważ interfejs Maps JavaScript API wyzwala te ostatnie zdarzenia niezależnie, getBounds()
może nie raportować przydatnych wyników, dopóki widok nie zostanie zmieniony w autorytatywny sposób. Jeśli chcesz getBounds()
po takim zdarzeniu, zacznij zamiast tego nasłuchiwać zdarzenia bounds_changed
.
Przykład: zdarzenia związane z edytowaniem i przeciąganiem kształtów
Gdy kształt jest edytowany lub przeciągany, po zakończeniu działania następuje wywołanie zdarzenia. Listę zdarzeń i fragmentów kodu znajdziesz w sekcji Kształty.
Zobacz przykład (rectangle-event.html)
Dostęp do argumentów w zdarzeniach interfejsu
Zdarzenia interfejsu użytkownika w interfejsie JavaScript API Maps zwykle przekazują argument zdarzenia, do którego odbiornik zdarzenia może uzyskać dostęp, aby poznać stan interfejsu użytkownika w momencie wystąpienia zdarzenia. Na przykład zdarzenie interfejsu użytkownika 'click'
zwykle przekazuje obiekt MouseEvent
zawierający właściwość latLng
oznaczającą kliknięte miejsce na mapie. Pamiętaj, że to zachowanie jest charakterystyczne dla zdarzeń interfejsu użytkownika. Zmiany stanu MVC nie przekazują argumentów w swoich zdarzeniach.
Argumenty zdarzenia możesz uzyskać w detektorze zdarzeń w taki sam sposób, w jaki uzyskujesz dostęp do właściwości obiektu. W tym przykładzie dodawane jest zdarzenie detektora dla mapy, a po kliknięciu przez użytkownika klikniętej lokalizacji na mapie tworzony jest znacznik.
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();
Wypróbuj próbkę
Używanie funkcji zamykania w detektorach zdarzeń
Podczas wykonywania detektora zdarzeń często warto mieć zarówno dane prywatne, jak i dane trwałe powiązane z obiektem. JavaScript nie obsługuje „prywatnych” danych instancji, ale obsługuje closures, które umożliwiają funkcjom wewnętrznym dostęp do zewnętrznych zmiennych. Zamknięcia są przydatne w słuchaczach zdarzeń, ponieważ umożliwiają dostęp do zmiennych, które zwykle nie są przypisane do obiektów, w których występują zdarzenia.
W tym przykładzie w odbiorniku zdarzeń używana jest funkcja zamykająca, aby przypisać tajną wiadomość do zestawu znaczników. Kliknięcie każdego znacznika ujawnia część tajnej wiadomości, która nie jest zawarta w samym znaczniku.
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();
Wypróbuj próbkę
Pobieranie i ustawianie właściwości w modułach obsługi zdarzeń
Żadne z wydarzeń zmiany stanu MVC w systemie zdarzeń interfejsu Maps JavaScript API nie przekazuje argumentów, gdy jest wywoływane. (Zdarzenia użytkownika przekazują argumenty, które można sprawdzić). Jeśli chcesz sprawdzić właściwość w przypadku zmiany stanu MVC, musisz wywołać odpowiednią metodę getProperty()
tego obiektu. Ta inspekcja zawsze pobiera bieżący stan obiektu MVC, który może nie być stanem z czasu pierwszego wywołania zdarzenia.
Uwaga: jawne ustawianie właściwości w obiekcie funkcji obsługi zdarzenia, który reaguje na zmianę stanu tego konkretnego obiektu, może powodować nieprzewidywalne lub niepożądane działanie. Ustawienie takiej właściwości spowoduje np. uruchomienie nowego zdarzenia, a jeśli zawsze ustawiasz w tym obiekcie właściwości, możesz w efekcie utworzyć nieskończoną pętlę.
W przykładzie poniżej skonfigurowaliśmy przetwarzacz zdarzeń, aby reagował na zdarzenia zoom, wyświetlając okno z informacjami o tym poziomie.
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();
Wypróbuj próbkę
Nasłuchiwanie zdarzeń DOM
Model zdarzeń interfejsu Maps JavaScript API tworzy własne zdarzenia niestandardowe i nimi zarządza. Jednak DOM (Document Object Model) w przeglądarce tworzy i wysyła też własne zdarzenia zgodnie z konkretnym modelem zdarzeń przeglądarki. Jeśli chcesz rejestrować te zdarzenia i na nie odpowiadać, możesz użyć w interfejsie Maps JavaScript API metody statycznej addDomListener()
, która umożliwia nasłuchiwanie zdarzeń DOM i wiązanie ich z nimi.
Ta wygodna metoda ma podpis pokazany 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, takie jak
window
lubdocument.body.myform
- elementy o nazwie, np.
document.getElementById("foo")
;
Pamiętaj, że addDomListener()
przekazuje wskazane zdarzenie do przeglądarki, która obsługuje je zgodnie z modelem zdarzenia DOM przeglądarki. Jednak prawie wszystkie nowoczesne przeglądarki obsługują co najmniej DOM Level 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> <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>
Wypróbuj próbkę
Powyższy kod jest kodem interfejsu Maps JavaScript API, ale metoda addDomListener()
łączy się z obiektem window
przeglądarki i pozwala interfejsowi API na komunikację z obiektmi spoza normalnej domeny interfejsu API.
Usuwanie detektorów zdarzeń
Aby usunąć konkretny detektor zdarzeń, musisz go przypisać do zmiennej. Następnie możesz wywołać funkcję removeListener()
, podając nazwę zmiennej, do której został przypisany detektor.
var listener1 = marker.addListener('click', aFunction); google.maps.event.removeListener(listener1);
Aby usunąć wszystkich słuchaczy z określonej instancji, wywołaj funkcję clearInstanceListeners()
, podają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 usunąć wszystkich detektorów określonego typu zdarzenia w konkretnym wystąpieniu, wywołaj funkcję clearListeners()
, podając nazwę wystąpienia 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 dotyczącej przestrzeni nazw google.maps.event.
Sprawdzanie błędów uwierzytelniania
Jeśli chcesz za pomocą kodu wykrywać błędy uwierzytelniania (np. aby automatycznie wysyłać sygnał beacon), możesz przygotować funkcję wywołania zwrotnego.
Jeśli zdefiniowana jest podana niżej funkcja globalna, zostanie ona wywołana, gdy uwierzytelnianie się nie powiedzie.
function gm_authFailure() { /* Code */ };