Wydarzenia

Wybierz platformę: Android iOS JavaScript

Na tej stronie opisujemy zdarzenia interfejsu i błędy, których możesz nasłuchiwać i które możesz obsługiwać programowo.

Zdarzenia interfejsu

JavaScript w przeglądarce jest sterowany zdarzeniami, co oznacza, że reaguje na interakcje, generując zdarzenia, i oczekuje, że program będzie nasłuchiwać interesujących zdarzeń. Istnieją 2 typy zdarzeń:

  • Zdarzenia użytkownika (np. zdarzenia myszy "click") są propagowane z DOM do interfejsu Maps JavaScript API. Te zdarzenia są oddzielne 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 interfejsu Maps JavaScript API eksportuje kilka nazwanych zdarzeń. Programy zainteresowane określonymi zdarzeniami rejestrują dla nich detektory zdarzeń i wykonują kod, gdy te zdarzenia zostaną odebrane. Aby zarejestrować moduły obsługi zdarzeń w obiekcie, wywołują funkcję addListener().

Poniższy przykład 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, który je zawiera.

Zdarzenia interfejsu

Niektóre obiekty w interfejsie Maps JavaScript API są zaprojektowane tak, aby reagować na zdarzenia użytkownika, takie jak zdarzenia myszy lub klawiatury. Oto na przykład niektóre zdarzenia użytkownika, których może nasłuchiwać obiekt google.maps.marker.AdvancedMarkerElement:

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

Pełną listę znajdziesz w klasie AdvancedMarkerElement 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 te mechanizmy do nasłuchiwania zdarzeń DOM i reagowania na nie bez konieczności obsługi różnych osobliwości międzyprzeglądarkowych. Te zdarzenia zwykle przekazują też argumenty w ramach zdarzenia, które wskazują stan interfejsu (np. położenie kursora myszy).

Zmiany stanu MVC

Obiekty MVC zwykle zawierają stan. Gdy właściwość obiektu ulegnie zmianie, interfejs Maps JavaScript API wywoła zdarzenie, że właściwość została zmieniona. Na przykład interfejs API wywoła zdarzenie zoom_changed na mapie, gdy zmieni się poziom powiększenia mapy. Możesz też przechwytywać te zmiany stanu, wywołując funkcję addListener() w celu zarejestrowania modułów obsługi zdarzeń w obiekcie.

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

Obsługa zdarzeń

Aby zarejestrować się w celu otrzymywania powiadomień o zdarzeniach, użyj modułu obsługi zdarzeń addListener(). Ta metoda przyjmuje zdarzenie, którego ma nasłuchiwać, oraz a funkcję, która ma być wywoływana, gdy wystąpi określone zdarzenie.

Przykład: zdarzenia mapy i znacznika

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

TypeScript

async function init() {
    // Request needed libraries.
    const [{ AdvancedMarkerElement }, { LatLng }] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('core'),
        google.maps.importLibrary('maps'),
    ]);

    // Retrieve the map element.
    const mapElement = document.querySelector('gmp-map')!;

    // Get the inner map from the map element.
    const innerMap = mapElement.innerMap;

    const originalPosition = new LatLng(mapElement.center!);

    const marker = new AdvancedMarkerElement({
        position: originalPosition,
        map: innerMap,
        title: 'Click to zoom',
        gmpClickable: true,
    });

    innerMap.addListener('center_changed', () => {
        // 3 seconds after the center of the map has changed,
        // pan back to the marker.
        window.setTimeout(() => {
            innerMap.panTo(originalPosition);
        }, 3000);
    });

    // Zoom in when the marker is clicked.
    marker.addEventListener('gmp-click', () => {
        innerMap.setZoom(8);
        innerMap.setCenter(originalPosition);
    });
}

void init();

JavaScript

async function init() {
    // Request needed libraries.
    const [{ AdvancedMarkerElement }, { LatLng }] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('core'),
        google.maps.importLibrary('maps'),
    ]);

    // Retrieve the map element.
    const mapElement = document.querySelector('gmp-map');

    // Get the inner map from the map element.
    const innerMap = mapElement.innerMap;

    const originalPosition = new LatLng(mapElement.center);

    const marker = new AdvancedMarkerElement({
        position: originalPosition,
        map: innerMap,
        title: 'Click to zoom',
        gmpClickable: true,
    });

    innerMap.addListener('center_changed', () => {
        // 3 seconds after the center of the map has changed,
        // pan back to the marker.
        window.setTimeout(() => {
            innerMap.panTo(originalPosition);
        }, 3000);
    });

    // Zoom in when the marker is clicked.
    marker.addEventListener('gmp-click', () => {
        innerMap.setZoom(8);
        innerMap.setCenter(originalPosition);
    });
}

void init();
Zobacz przykład

Wskazówka: jeśli próbujesz wykryć zmianę w widocznym obszarze, użyj konkretnego zdarzenia bounds_changed zamiast zdarzeń składowych zoom_changed i center_changed. Ponieważ interfejs Maps JavaScript API wywołuje te ostatnie zdarzenia niezależnie, getBounds() może nie zwracać przydatnych wyników dopóki widoczny obszar nie zostanie autorytatywnie zmieniony. Jeśli chcesz użyć funkcji getBounds() po takim zdarzeniu, nasłuchuj zdarzenia bounds_changed.

Przykład: zdarzenia edycji i przeciągania kształtu

Gdy kształt jest edytowany lub przeciągany, po zakończeniu działania wywoływane jest zdarzenie. Listę zdarzeń i fragmenty kodu znajdziesz w sekcji Kształty.

Zobacz przykład (rectangle-event.html)

Dostęp do argumentów w zdarzeniach interfejsu

Zdarzenia interfejsu w interfejsie Maps JavaScript API zwykle przekazują argument zdarzenia, do którego może uzyskać dostęp detektor zdarzeń, wskazując stan interfejsu w momencie wystąpienia zdarzenia. Na przykład zdarzenie interfejsu 'click' zwykle przekazuje element MouseEvent zawierający właściwość latLng, która oznacza klikniętą lokalizację na mapie. Pamiętaj, że to zachowanie jest unikalne dla zdarzeń interfejsu . Zmiany stanu MVC nie przekazują argumentów w swoich zdarzeniach.

Możesz uzyskać dostęp do argumentów zdarzenia w detektorze zdarzeń w taki sam sposób jak do właściwości obiektu. Poniższy przykład dodaje detektor zdarzeń do mapy i tworzy znacznik, gdy użytkownik kliknie mapę w klikniętej lokalizacji.

TypeScript

async function init() {
    // Request needed libraries.
    const [{ AdvancedMarkerElement }] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('maps'),
    ]);

    const mapElement = document.querySelector('gmp-map')!;
    const innerMap = mapElement.innerMap;

    innerMap.addListener('click', (event: google.maps.MapMouseEvent) => {
        if (!event.latLng) return;
        new AdvancedMarkerElement({
            position: event.latLng,
            map: innerMap,
        });
        innerMap.panTo(event.latLng);
    });
}

void init();

JavaScript

async function init() {
    // Request needed libraries.
    const [{ AdvancedMarkerElement }] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('maps'),
    ]);

    const mapElement = document.querySelector('gmp-map');
    const innerMap = mapElement.innerMap;

    innerMap.addListener('click', (event) => {
        if (!event.latLng) return;
        new AdvancedMarkerElement({
            position: event.latLng,
            map: innerMap,
        });
        innerMap.panTo(event.latLng);
    });
}

void init();
Zobacz przykład

Używanie domknięć w detektorach zdarzeń

Podczas wykonywania detektora zdarzeń często korzystne jest dołączenie do obiektu danych prywatnych i trwałych. JavaScript nie obsługuje „prywatnych” danych instancji, ale obsługuje domknięcia, które umożliwiają funkcjom wewnętrznym dostęp do zmiennych zewnętrznych. Domknięcia są przydatne w detektorach zdarzeń, aby uzyskać dostęp do zmiennych, które zwykle nie są dołączone do obiektów, w których występują zdarzenia.

Poniższy przykład używa domknięcia funkcji w detektorze zdarzeń, aby przypisać tajną wiadomość do zestawu znaczników. Kliknięcie każdego znacznika spowoduje wyświetlenie części tajnej wiadomości, która nie jest zawarta w samym znaczniku.

TypeScript

async function init() {
    // Request needed libraries.
    const [{ AdvancedMarkerElement }] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('maps'),
    ]);

    const mapElement = document.querySelector('gmp-map')!;
    const innerMap = mapElement.innerMap;

    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.
    innerMap.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 (const secretMessage of secretMessages) {
        const marker = new AdvancedMarkerElement({
            position: {
                lat: bounds.south + latSpan * Math.random(),
                lng: bounds.west + lngSpan * Math.random(),
            },
            map: innerMap,
        });

        void attachSecretMessage(marker, secretMessage);
    }
}

// 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.
async function attachSecretMessage(
    marker: google.maps.marker.AdvancedMarkerElement,
    secretMessage: string
) {
    const { InfoWindow } = await google.maps.importLibrary('maps');

    const infoWindow = new InfoWindow({
        content: secretMessage,
    });

    marker.addListener('gmp-click', () => {
        infoWindow.open(marker.map, marker);
    });
}

void init();

JavaScript

async function init() {
    // Request needed libraries.
    const [{ AdvancedMarkerElement }] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('maps'),
    ]);

    const mapElement = document.querySelector('gmp-map');
    const innerMap = mapElement.innerMap;

    const bounds = {
        north: -25.363882,
        south: -31.203405,
        east: 131.044922,
        west: 125.244141,
    };

    // Display the area between the location southWest and northEast.
    innerMap.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 (const secretMessage of secretMessages) {
        const marker = new AdvancedMarkerElement({
            position: {
                lat: bounds.south + latSpan * Math.random(),
                lng: bounds.west + lngSpan * Math.random(),
            },
            map: innerMap,
        });

        void attachSecretMessage(marker, secretMessage);
    }
}

// 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.
async function attachSecretMessage(marker, secretMessage) {
    const { InfoWindow } = await google.maps.importLibrary('maps');

    const infoWindow = new InfoWindow({
        content: secretMessage,
    });

    marker.addListener('gmp-click', () => {
        infoWindow.open(marker.map, marker);
    });
}

void init();
Zobacz przykład

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

Żadne zdarzenia zmiany stanu MVC w systemie zdarzeń interfejsu Maps JavaScript API nie przekazują argumentów, gdy zdarzenie 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 jawnie wywołać odpowiednią getProperty() metodę w tym obiekcie. Ta kontrola zawsze pobierze bieżący stan obiektu MVC , który może nie być stanem, w którym zdarzenie zostało wywołane po raz pierwszy.

Uwaga: jawne ustawienie właściwości w module obsługi zdarzeń, który reaguje na zmianę stanu tej konkretnej właściwości może spowodować nieprzewidywalne lub niepożądane zachowanie. Ustawienie takiej właściwości spowoduje na przykład wywołanie nowego zdarzenia, a jeśli zawsze ustawisz właściwość w tym module obsługi zdarzeń, możesz utworzyć nieskończoną pętlę.

Poniższy przykład pokazuje, jak skonfigurować moduł obsługi zdarzeń, aby reagować na zdarzenia powiększenia, wyświetlając okno informacyjne z tym poziomem.

TypeScript

async function init() {
    // Request needed libraries.
    const { InfoWindow } = await google.maps.importLibrary('maps');

    const mapElement = document.querySelector('gmp-map')!;
    const innerMap = mapElement.innerMap;

    const infoWindow = new InfoWindow({
        content: 'Change the zoom level',
        position: mapElement.center,
    });

    infoWindow.open(innerMap);

    innerMap.addListener('zoom_changed', () => {
        infoWindow.setContent('Zoom: ' + innerMap.getZoom()!);
    });
}

void init();

JavaScript

async function init() {
    // Request needed libraries.
    const { InfoWindow } = await google.maps.importLibrary('maps');

    const mapElement = document.querySelector('gmp-map');
    const innerMap = mapElement.innerMap;

    const infoWindow = new InfoWindow({
        content: 'Change the zoom level',
        position: mapElement.center,
    });

    infoWindow.open(innerMap);

    innerMap.addListener('zoom_changed', () => {
        infoWindow.setContent('Zoom: ' + innerMap.getZoom());
    });
}

void init();
Zobacz przykład

Usuwanie detektorów zdarzeń

Aby usunąć konkretny detektor zdarzeń, musi on być przypisany do zmiennej. Następnie możesz wywołać funkcję removeListener(), przekazując nazwę zmiennej, do której został przypisany detektor.

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

google.maps.event.removeListener(listener1);

Aby usunąć wszystkie detektory z konkretnej instancji, 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 usunąć wszystkie detektory określonego typu zdarzenia dla konkretnej instancji, wywołaj funkcję 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.

Nasłuchiwanie błędów uwierzytelniania

Jeśli chcesz programowo wykryć błąd uwierzytelniania (np. aby automatycznie wysłać sygnał nawigacyjny), możesz przygotować funkcję wywołania zwrotnego. Jeśli zdefiniowana jest ta funkcja globalna, zostanie ona wywołana, gdy uwierzytelnianie się nie powiedzie. function gm_authFailure() { /* Code */ };

W TypeScript może być konieczne dodanie funkcji do zakresu globalnego, jak pokazano poniżej:

// Define the callback function.
window.gm_authFailure = () => {
  console.error("Google Maps failed to authenticate.");
  /* Code */
};

// Add gm_authFailure to the global scope.
declare global {
  interface Window {
    gm_authFailure?: () => void;
  }
}
export {};