На этой странице описываются события пользовательского интерфейса и события ошибок, которые можно прослушивать и обрабатывать программными способами.
События пользовательского интерфейса
В браузерах код 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.AdvancedMarkerElement может прослушивать следующие пользовательские события:
'gmp-click''gmp-drag''gmp-dragstart''gmp-dragend'
Полный список событий приведен в описании класса AdvancedMarkerElement. Эти события похожи на стандартные события 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
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();
Совет. Чтобы обнаруживать изменения области просмотра, используйте специальное событие bounds_changed, а не zoom_changed и center_changed. Поскольку API Карт вызывает последние два события по отдельности, метод getBounds() может не возвратить нужные результаты, пока область просмотра не будет принудительно изменена. Если вы хотите выполнить метод getBounds() после такого события, обязательно добавьте прослушиватель для события bounds_changed.
Пример: события перетаскивания и изменения фигур
Событие срабатывает, когда пользователь заканчивает изменять или перетаскивать фигуру. Список событий с примерами кода приведен в статье Фигуры.
Посмотреть пример (rectangle-event.html)
Как пользоваться доступом к аргументам в событиях пользовательского интерфейса
События пользовательского интерфейса в Maps JavaScript API обычно передают аргумент события, который доступен прослушивателю событий, указывающий на состояние пользовательского интерфейса в момент этого события. Например, событие интерфейса пользователя 'click' обычно передает событие MouseEvent, содержащее свойство latLng, обозначающее место нажатия кнопки мыши на карте. Обратите внимание, что это касается только событий пользовательского интерфейса; события изменения состояния объекта MVC не передают аргументы.
Обращение к аргументам событий в прослушивателе происходит так же, как и обращение к свойствам объекта. Показанный ниже код добавляет прослушиватель событий для карты и создает маркер, когда пользователь нажимает на карту в определенной точке.
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();
Как использовать замыкания в прослушивателях событий
При выполнении прослушивателя событий имеет смысл прикреплять к объекту как приватные, так и постоянные данные. Хотя в JavaScript не поддерживаются приватные данные экземпляра (с атрибутом private), можно использовать замыкания, с помощью которых внутренние функции обращаются к внешним переменным. Замыкания в прослушивателях событий удобны для обращения к переменным, не прикрепленным к объектам, к которым относятся события.
В примере ниже замыкание функции в прослушивателе событий присваивает набору маркеров скрытое сообщение. При нажатии на маркер показывается часть скрытого сообщения, не включенного в сам маркер.
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, gmpClickable: true, }); 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.addEventListener('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, gmpClickable: true, }); 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.addEventListener('gmp-click', () => { infoWindow.open(marker.map, marker); }); } void init();
Как получить и установить свойства в обработчиках событий
События изменения состояния объекта MVC в системе событий Maps JavaScript API никогда не передают аргументы при возникновении события. (Пользовательские события передают аргументы, к которым можно обращаться.) Если необходимо получить значение свойства при изменении состояния объекта MVC, нужно явно вызвать соответствующий метод getProperty() этого объекта. В этом случае всегда возвращается текущее состояние объекта MVC, которое может не совпадать с состоянием на момент события.
Примечание. Если явно указать значение свойства в обработчике событий, отвечающем на изменение состояния именно этого свойства, результат может быть непредсказуемым или нежелательным. Например, если указать значение свойства, будет отправлено новое событие. Таким образом, если каждый раз присваивать свойству значение в обработчике событий, возникнет бесконечный цикл.
В примере ниже показано, как настроить обработчик событий для ответа на события масштабирования путем вывода информационного окна с соответствующим уровнем.
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();
Как удалять прослушиватели событий
Для удаления определенного прослушивателя событий необходимо, чтобы он был присвоен переменной. В этом случае можно вызвать метод 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 */ };
В TypeScript может потребоваться добавить функцию в глобальную область видимости, как показано ниже.
// 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 {};