События

Выберите платформу: Android iOS JavaScript

На этой странице описываются события пользовательского интерфейса и события ошибок, которые можно прослушивать и обрабатывать программными способами.

События пользовательского интерфейса

В браузерах код JavaScript управляется событиями, т. е. реагирует на взаимодействие, создавая события, и ожидает, что программа будет прослушивать нужные события. События бывают двух типов:

  • Пользовательские события (например, события нажатия кнопок мыши), которые передаются из DOM в Maps JavaScript API. Они отличаются от стандартных событий DOM.
  • Уведомления об изменениях состояния MVC, отражающие изменения объектов Maps JavaScript API. В их названиях используется соглашение property_changed.

Каждый объект Maps JavaScript API экспортирует определенное количество именованных событий. Программы, обрабатывающие определенные события, регистрируют для них прослушиватели JavaScript и выполняют при их получении код. Для регистрации обработчиков событий в объекте используется метод addListener().

В примере ниже показано, какие события активируются google.maps.Map при взаимодействии с картой.

Полный список событий можно найти в документации по Maps JavaScript API. Перечень событий приводится в отдельном разделе для каждого объекта, содержащего события.

События пользовательского интерфейса

Некоторые объекты в Maps JavaScript API могут реагировать на действия пользователя, например на события мыши и клавиатуры. Например, объект google.maps.Marker может прослушивать следующие пользовательские события:

  • 'click'
  • 'dblclick'
  • 'mouseup'
  • 'mousedown'
  • 'mouseover'
  • 'mouseout'

Полный список событий приведен в описании класса Marker. Эти события похожи на стандартные события DOM, однако в действительности они являются частью Maps JavaScript API. Поскольку в различных браузерах реализованы разные модели событий DOM, Maps JavaScript API предоставляет универсальные механизмы для прослушивания событий DOM и реагирования на них без необходимости учета особенностей браузеров. Также вместе с этими событиями обычно передаются аргументы, указывающие на определенное состояние пользовательского интерфейса (например, положение указателя мыши).

Изменение состояний MVC

Объекты MVC обычно содержат информацию о состоянии. Когда свойство объекта меняется, Maps JavaScript API вызывает событие, например при изменении масштаба карты API вызывает для нее событие zoom_changed. Чтобы перехватывать изменения состояния, зарегистрируйте обработчики событий addListener() для объекта.

События пользовательского интерфейса и изменения состояния MVC могут выглядеть похоже, но в коде они обычно обрабатываются разными способами. Например, события MVC не передают аргументы. Чтобы проанализировать измененное свойство объекта MVC, повлекшее изменение состояния, для объекта нужно вызвать подходящий метод getProperty.

Обработка событий

Чтобы получать уведомления о событиях, необходимо зарегистрировать обработчик с помощью метода addListener(). Методу передаются прослушиваемое событие и вызываемая при наступлении указанного события функция.

Пример: события карты и маркеров

В примере кода ниже пользовательские события используются вместе с событиями изменения состояния. Обработчик прикрепляется к маркеру, увеличивающему масштаб карты при нажатии. Кроме того, на карту добавляется обработчик, который прослушивает изменения свойства center. Через три секунды после получения события center_changed карта перемещается обратно к маркеру.

TypeScript

function initMap(): void {
  const myLatlng = { lat: -25.363, lng: 131.044 };

  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 4,
      center: myLatlng,
    }
  );

  const marker = new google.maps.Marker({
    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.getPosition() as google.maps.LatLng);
    }, 3000);
  });

  marker.addListener("click", () => {
    map.setZoom(8);
    map.setCenter(marker.getPosition() as google.maps.LatLng);
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const myLatlng = { lat: -25.363, lng: 131.044 };
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: myLatlng,
  });
  const marker = new google.maps.Marker({
    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.getPosition());
    }, 3000);
  });
  marker.addListener("click", () => {
    map.setZoom(8);
    map.setCenter(marker.getPosition());
  });
}

window.initMap = initMap;
Посмотреть пример

Примеры кода

Совет. Чтобы обнаруживать изменения области просмотра, используйте специальное событие bounds_changed, а не zoom_changed и center_changed. Поскольку API Карт вызывает последние два события по отдельности, метод getBounds() может не возвратить нужные результаты, пока область просмотра не будет принудительно изменена. Если вы хотите выполнить метод getBounds() после такого события, обязательно добавьте прослушиватель для события bounds_changed.

Пример: события перетаскивания и изменения фигур

Событие срабатывает, когда пользователь заканчивает изменять или перетаскивать фигуру. Список событий с примерами кода приведен в статье Фигуры.

Посмотреть пример (rectangle-event.html)

Доступ к аргументам в событиях пользовательского интерфейса

События пользовательского интерфейса в Maps JavaScript API обычно передают аргументы событий, указывая состояние пользовательского интерфейса на момент события. Аргумент можно получить с помощью прослушивателя. Например, событие интерфейса пользователя 'click' обычно передает событие MouseEvent, содержащее свойство latLng, обозначающее место нажатия кнопки мыши на карте. Обратите внимание на то, что это касается только событий пользовательского интерфейса; события изменения состояния объекта MVC не передают аргументы.

Доступ к аргументам событий осуществляется в прослушивателях так же, как и к свойствам объекта. Показанный ниже код добавляет прослушиватель событий для карты и создает маркер, когда пользователь нажимает на карту в определенной точке.

TypeScript

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 4,
      center: { lat: -25.363882, lng: 131.044922 },
    }
  );

  map.addListener("click", (e) => {
    placeMarkerAndPanTo(e.latLng, map);
  });
}

function placeMarkerAndPanTo(latLng: google.maps.LatLng, map: google.maps.Map) {
  new google.maps.Marker({
    position: latLng,
    map: map,
  });
  map.panTo(latLng);
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: { lat: -25.363882, lng: 131.044922 },
  });

  map.addListener("click", (e) => {
    placeMarkerAndPanTo(e.latLng, map);
  });
}

function placeMarkerAndPanTo(latLng, map) {
  new google.maps.Marker({
    position: latLng,
    map: map,
  });
  map.panTo(latLng);
}

window.initMap = initMap;
Посмотреть пример

Примеры кода

Использование замыканий в прослушивателях событий

При выполнении прослушивателя событий имеет смысл прикреплять к объекту как приватные, так и постоянные данные. Хотя в JavaScript не поддерживаются приватные данные экземпляра (с атрибутом private), можно использовать замыкания, с помощью которых внутренние функции обращаются к внешним переменным. Замыкания в прослушивателях событий удобны для доступа к переменным, не прикрепленным к объектам, к которым относятся события.

В примере ниже замыкание функции в прослушивателе событий присваивает набору маркеров скрытое сообщение. При нажатии на маркер показывается часть скрытого сообщения, не включенного в сам маркер.

TypeScript

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 4,
      center: { lat: -25.363882, lng: 131.044922 },
    }
  );

  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({
      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,
  secretMessage: string
) {
  const infowindow = new google.maps.InfoWindow({
    content: secretMessage,
  });

  marker.addListener("click", () => {
    infowindow.open(marker.get("map"), marker);
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: { lat: -25.363882, lng: 131.044922 },
  });
  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({
      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.get("map"), marker);
  });
}

window.initMap = initMap;
Посмотреть пример

Примеры кода

Получение и установка свойств в обработчиках событий

События изменения состояния объекта MVC в системе событий Maps JavaScript API никогда не передают аргументы при возникновении события. Пользовательские события передают аргументы, которые можно проанализировать. Если необходимо исследовать свойство при изменении состояния объекта MVC, нужно явно вызвать подходящий метод getProperty() для этого объекта. В этом случае всегда возвращается текущее состояние объекта MVC, которое может не совпадать с состоянием на момент события.

Примечание. Если явно указать значение свойства в обработчике событий, отвечающем на изменение состояния именно этого свойства, результат может быть непредсказуемым или нежелательным. Например, если указать значение свойства, будет отправлено новое событие. Таким образом, если каждый раз присваивать свойству значение в обработчике событий, возникнет бесконечный цикл.

В примере ниже показан обработчик, который в ответ на события масштабирования показывает информационное окно с соответствующим значением масштаба.

TypeScript

function initMap(): void {
  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()!);
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  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());
  });
}

window.initMap = initMap;
Посмотреть пример

Примеры кода

Прослушивание событий DOM

Модель событий Maps JavaScript API создает собственные персонализированные события и управляет ими. Однако DOM (модель объектов документов) также создает и отправляет собственные события в соответствии с используемой моделью событий определенного браузера. Чтобы перехватывать эти события и отвечать на них, в Maps JavaScript API предусмотрен статический метод addDomListener() для прослушивания и привязки событий DOM.

Вызов этого вспомогательного метода записывается следующим образом:

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

Здесь instance может быть любым элементом DOM, поддерживаемым браузером, в том числе:

  • иерархическими членами DOM, например window или document.body.myform;
  • именованными элементами, например document.getElementById("foo").

Обратите внимание на то, что метод addDomListener() просто передает указанное событие браузеру, который обрабатывает его в соответствии со своей моделью событий DOM. Практически все современные браузеры поддерживают DOM уровня 2 или выше. Подробные сведения можно найти в справочной документации Mozilla по уровням DOM.

TypeScript

function initMap(): void {
  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!");
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  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!");
  });
}

window.initMap = 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>

    <!--
      The `defer` attribute causes the callback to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises.
      See https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
      defer
    ></script>
  </body>
</html>
Посмотреть пример

Примеры кода

Хотя приведенный выше код является кодом Maps JavaScript API, метод addDomListener() привязывается к объекту window браузера и позволяет API взаимодействовать с объектами за пределами своего домена.

Удаление прослушивателей событий

Для удаления определенного прослушивателя событий необходимо, чтобы он был присвоен переменной. В этом случае можно вызвать метод removeListener(), передав ему имя переменной, которой присвоен прослушиватель.

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

google.maps.event.removeListener(listener1);

Чтобы удалить все прослушиватели из определенного экземпляра, нужно вызвать clearInstanceListeners(), передав имя экземпляра.

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

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

Чтобы удалить все прослушиватели определенного типа событий для определенного экземпляра, нужно вызвать метод clearListeners() и передать ему имя экземпляра вместе с именем события.

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

Дополнительные сведения можно найти в документации по пространству имен google.maps.event.

Прослушивание ошибок аутентификации

Если вы хотите программным способом обнаруживать ошибки аутентификации, например чтобы настроить автоматическую отправку маячка, можно подготовить функцию обратного вызова. Если определить приведенную ниже глобальную функцию, она будет вызываться в случае сбоя аутентификации. function gm_authFailure() { /* Code */ };