Trang này mô tả các sự kiện giao diện người dùng và sự kiện lỗi mà bạn có thể theo dõi và xử lý theo phương thức lập trình.
Sự kiện giao diện người dùng
JavaScript trong trình duyệt là dựa trên sự kiện, tức là JavaScript phản hồi các lượt tương tác bằng cách tạo sự kiện và mong đợi một chương trình lắng nghe các sự kiện thú vị. Có hai loại sự kiện:
- Các sự kiện của người dùng (chẳng hạn như sự kiện chuột "click") được truyền từ DOM đến Maps JavaScript API. Những sự kiện này tách biệt và khác biệt với các sự kiện DOM tiêu chuẩn.
- Thông báo thay đổi trạng thái MVC phản ánh các thay đổi trong các đối tượng Maps JavaScript API và được đặt tên theo quy ước
property_changed.
Mỗi đối tượng Maps JavaScript API xuất một số sự kiện có tên.
Các chương trình quan tâm đến một số sự kiện nhất định sẽ đăng ký trình nghe sự kiện JavaScript cho những sự kiện đó và thực thi mã khi những sự kiện đó được nhận bằng cách gọi addListener() để đăng ký trình xử lý sự kiện trên đối tượng.
Mẫu sau đây cho biết những sự kiện nào được kích hoạt bởi google.maps.Map khi bạn tương tác với bản đồ.
Để xem danh sách đầy đủ các sự kiện, hãy tham khảo Tài liệu tham khảo về Maps JavaScript API. Các sự kiện được liệt kê trong một phần riêng cho từng đối tượng chứa sự kiện.
Sự kiện giao diện người dùng
Một số đối tượng trong Maps JavaScript API được thiết kế để phản hồi các sự kiện của người dùng, chẳng hạn như sự kiện chuột hoặc bàn phím. Ví dụ: sau đây là một số sự kiện người dùng mà đối tượng google.maps.marker.AdvancedMarkerElement có thể theo dõi:
'click''drag''dragend''dragstart''gmp-click'
Để xem danh sách đầy đủ, hãy xem lớp AdvancedMarkerElement. Những sự kiện này có thể trông giống như các sự kiện DOM tiêu chuẩn, nhưng thực tế chúng là một phần của Maps JavaScript API. Vì các trình duyệt khác nhau triển khai các mô hình sự kiện DOM khác nhau, nên Maps JavaScript API cung cấp những cơ chế này để theo dõi và phản hồi các sự kiện DOM mà không cần xử lý nhiều đặc điểm riêng của từng trình duyệt. Các sự kiện này cũng thường truyền các đối số trong sự kiện, ghi chú một số trạng thái giao diện người dùng (chẳng hạn như vị trí chuột).
Các thay đổi về trạng thái MVC
Các đối tượng MVC thường chứa trạng thái. Bất cứ khi nào thuộc tính của một đối tượng thay đổi, API JavaScript của Maps sẽ kích hoạt một sự kiện cho biết thuộc tính đó đã thay đổi.
Ví dụ: API sẽ kích hoạt sự kiện zoom_changed trên bản đồ khi mức thu phóng của bản đồ thay đổi. Bạn cũng có thể chặn những thay đổi về trạng thái này bằng cách gọi addListener() để đăng ký trình xử lý sự kiện trên đối tượng.
Các sự kiện của người dùng và thay đổi trạng thái MVC có thể trông tương tự nhau, nhưng bạn nên xử lý chúng theo cách khác nhau trong mã của mình. Ví dụ: các sự kiện MVC không truyền đối số trong sự kiện của chúng. Kiểm tra thuộc tính đã thay đổi khi trạng thái MVC thay đổi bằng cách gọi phương thức getProperty thích hợp trên đối tượng đó.
Xử lý sự kiện
Để đăng ký nhận thông báo về sự kiện, hãy sử dụng trình xử lý sự kiện addListener(). Phương thức đó lấy một sự kiện để theo dõi và một hàm để gọi khi sự kiện được chỉ định xảy ra.
Ví dụ: Sự kiện Bản đồ và điểm đánh dấu
Mã sau đây kết hợp các sự kiện của người dùng với các sự kiện thay đổi trạng thái. Ví dụ này đính kèm một trình xử lý sự kiện vào một điểm đánh dấu để thu phóng bản đồ khi được nhấp vào. Thao tác này cũng đính kèm một trình xử lý sự kiện vào bản đồ để thay đổi thuộc tính center và di chuyển bản đồ trở lại điểm đánh dấu sau 3 giây khi nhận được sự kiện center_changed.
TypeScript
async function initMap() { // Request needed libraries. (await google.maps.importLibrary('maps')) as google.maps.MapsLibrary; (await google.maps.importLibrary('marker')) as google.maps.MarkerLibrary; // Retrieve the map element. const mapElement = document.querySelector( 'gmp-map' ) as google.maps.MapElement; // Get the inner map from the map element. const innerMap = mapElement.innerMap; const center = mapElement.center; const marker = new google.maps.marker.AdvancedMarkerElement({ position: center, 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(marker.position as google.maps.LatLng); }, 3000); }); // Zoom in when the marker is clicked. marker.addListener('gmp-click', () => { innerMap.setZoom(8); innerMap.setCenter(marker.position as google.maps.LatLng); }); } initMap();
JavaScript
async function initMap() { // Request needed libraries. (await google.maps.importLibrary('maps')); (await google.maps.importLibrary('marker')); // Retrieve the map element. const mapElement = document.querySelector('gmp-map'); // Get the inner map from the map element. const innerMap = mapElement.innerMap; const center = mapElement.center; const marker = new google.maps.marker.AdvancedMarkerElement({ position: center, 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(marker.position); }, 3000); }); // Zoom in when the marker is clicked. marker.addListener('gmp-click', () => { innerMap.setZoom(8); innerMap.setCenter(marker.position); }); } initMap();
Dùng thử mẫu
Lưu ý: Nếu bạn đang cố gắng phát hiện một thay đổi trong khung hiển thị, hãy nhớ sử dụng sự kiện bounds_changed cụ thể thay vì các sự kiện thành phần zoom_changed và center_changed. Vì Maps JavaScript API kích hoạt các sự kiện sau này một cách độc lập, nên getBounds() có thể không báo cáo kết quả hữu ích cho đến sau khi khung hiển thị thay đổi một cách đáng tin cậy. Nếu bạn muốn getBounds() sau một sự kiện như vậy, hãy nhớ theo dõi sự kiện bounds_changed.
Ví dụ: Sự kiện chỉnh sửa và kéo hình dạng
Khi một hình dạng được chỉnh sửa hoặc kéo, một sự kiện sẽ được kích hoạt khi hoàn tất thao tác. Để xem danh sách các sự kiện và một số đoạn mã, hãy xem phần Hình dạng.
Xem ví dụ (rectangle-event.html)
Truy cập vào đối số trong sự kiện trên giao diện người dùng
Các sự kiện trên giao diện người dùng trong Maps JavaScript API thường truyền một đối số sự kiện mà trình nghe sự kiện có thể truy cập, lưu ý trạng thái giao diện người dùng khi sự kiện xảy ra. Ví dụ: sự kiện 'click' trên giao diện người dùng thường truyền một MouseEvent chứa thuộc tính latLng biểu thị vị trí được nhấp trên bản đồ. Xin lưu ý rằng hành vi này chỉ xảy ra đối với các sự kiện trên giao diện người dùng; các thay đổi về trạng thái MVC không truyền đối số trong các sự kiện của chúng.
Bạn có thể truy cập vào các đối số của sự kiện trong một trình nghe sự kiện theo cách tương tự như cách bạn truy cập vào các thuộc tính của đối tượng. Ví dụ sau đây thêm một trình nghe sự kiện cho bản đồ và tạo một điểm đánh dấu khi người dùng nhấp vào bản đồ tại vị trí đã nhấp.
TypeScript
async function initMap() { // Request needed libraries. await google.maps.importLibrary("maps") as google.maps.MapsLibrary; await google.maps.importLibrary("marker") as google.maps.MarkerLibrary; const mapElement = document.querySelector('gmp-map') as google.maps.MapElement; const innerMap = mapElement.innerMap; innerMap.addListener("click", (e) => { placeMarkerAndPanTo(e.latLng, innerMap); }); } 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. await google.maps.importLibrary("maps"); await google.maps.importLibrary("marker"); const mapElement = document.querySelector('gmp-map'); const innerMap = mapElement.innerMap; innerMap.addListener("click", (e) => { placeMarkerAndPanTo(e.latLng, innerMap); }); } function placeMarkerAndPanTo(latLng, map) { new google.maps.marker.AdvancedMarkerElement({ position: latLng, map: map, }); map.panTo(latLng); } initMap();
Dùng thử mẫu
Sử dụng bao đóng trong trình nghe sự kiện
Khi thực thi một trình nghe sự kiện, bạn thường có lợi thế khi có cả dữ liệu riêng tư và dữ liệu liên tục được đính kèm vào một đối tượng. JavaScript không hỗ trợ dữ liệu phiên bản "riêng tư", nhưng có hỗ trợ đóng cho phép các hàm bên trong truy cập vào các biến bên ngoài. Các bao đóng rất hữu ích trong trình nghe sự kiện để truy cập vào các biến thường không được đính kèm vào các đối tượng mà sự kiện xảy ra.
Ví dụ sau đây sử dụng một bao đóng hàm trong trình nghe sự kiện để chỉ định một thông báo bí mật cho một nhóm điểm đánh dấu. Khi bạn nhấp vào mỗi điểm đánh dấu, một phần của thông điệp bí mật sẽ xuất hiện, nhưng phần này không nằm trong chính điểm đánh dấu.
TypeScript
async function initMap() { // Request needed libraries. (await google.maps.importLibrary('maps')) as google.maps.MapsLibrary; (await google.maps.importLibrary('marker')) as google.maps.MarkerLibrary; const mapElement = document.querySelector( 'gmp-map' ) as google.maps.MapElement; 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 (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: innerMap, }); 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('gmp-click', () => { infowindow.open(marker.map, marker); }); } initMap();
JavaScript
async function initMap() { // Request needed libraries. (await google.maps.importLibrary('maps')); (await google.maps.importLibrary('marker')); 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 (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: innerMap, }); 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('gmp-click', () => { infowindow.open(marker.map, marker); }); } initMap();
Dùng thử mẫu
Nhận và đặt thuộc tính trong Trình xử lý sự kiện
Không có sự kiện thay đổi trạng thái MVC nào trong hệ thống sự kiện Maps JavaScript API truyền đối số khi sự kiện được kích hoạt. (Sự kiện người dùng sẽ truyền các đối số mà bạn có thể kiểm tra.) Nếu cần kiểm tra một thuộc tính khi trạng thái MVC thay đổi, bạn nên gọi rõ ràng phương thức getProperty() thích hợp trên đối tượng đó. Hoạt động kiểm tra này sẽ luôn truy xuất trạng thái hiện tại của đối tượng MVC, có thể không phải là trạng thái khi sự kiện được kích hoạt lần đầu.
Lưu ý: Việc đặt rõ ràng một thuộc tính trong trình xử lý sự kiện phản hồi một thay đổi trạng thái của thuộc tính cụ thể đó có thể tạo ra hành vi không mong muốn và/hoặc khó đoán. Việc thiết lập một thuộc tính như vậy sẽ kích hoạt một sự kiện mới, chẳng hạn như nếu bạn luôn thiết lập một thuộc tính trong trình xử lý sự kiện này, thì bạn có thể tạo ra một vòng lặp vô hạn.
Ví dụ bên dưới cho thấy cách thiết lập một trình xử lý sự kiện để phản hồi các sự kiện thu phóng bằng cách hiển thị một cửa sổ thông tin cho biết cấp độ đó.
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();
Dùng thử mẫu
Xoá trình nghe sự kiện
Để xoá một trình nghe sự kiện cụ thể, bạn phải chỉ định trình nghe đó cho một biến. Sau đó, bạn có thể gọi removeListener(), truyền tên biến mà trình nghe được chỉ định.
var listener1 = marker.addListener('click', aFunction); google.maps.event.removeListener(listener1);
Để xoá tất cả trình nghe khỏi một phiên bản cụ thể, hãy gọi clearInstanceListeners(), truyền tên phiên bản.
var listener1 = marker.addListener('click', aFunction); var listener2 = marker.addListener('mouseover', bFunction); // Remove listener1 and listener2 from marker instance. google.maps.event.clearInstanceListeners(marker);
Để xoá tất cả trình nghe cho một loại sự kiện cụ thể của một phiên bản cụ thể, hãy gọi clearListeners(), truyền tên phiên bản và tên sự kiện.
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');
Để biết thêm thông tin, hãy tham khảo tài liệu tham khảo về không gian tên google.maps.event.
Nghe các lỗi xác thực
Nếu muốn phát hiện lỗi xác thực theo phương thức lập trình (ví dụ: để tự động gửi một tín hiệu), bạn có thể chuẩn bị một hàm callback.
Nếu hàm chung sau đây được xác định, thì hàm này sẽ được gọi khi quá trình xác thực không thành công.
function gm_authFailure() { /* Code */ };
Trong TypeScript, bạn có thể cần thêm hàm vào phạm vi chung như minh hoạ dưới đây:
// 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 {};