Tiện ích tự động hoàn thành địa điểm tạo một trường nhập văn bản, cung cấp thông tin dự đoán về địa điểm trong danh sách lựa chọn trên giao diện người dùng và trả về thông tin chi tiết về địa điểm theo lựa chọn của người dùng. Sử dụng tiện ích Tự động hoàn thành địa điểm để nhúng giao diện người dùng tự động hoàn thành đầy đủ và độc lập trên trang web của bạn.
Điều kiện tiên quyết
Để sử dụng tính năng Tự động hoàn thành địa điểm (Bản xem trước), bạn phải bật "API Địa điểm" trên dự án Google Cloud và chỉ định kênh beta (v: "beta"
) trong trình tải khởi động. Hãy xem phần Bắt đầu để biết thông tin chi tiết.
Tính năng mới
Tính năng Tự động hoàn thành địa điểm (Bản xem trước) đã được cải thiện theo những cách sau:
- Giao diện người dùng tiện ích Tự động hoàn thành hỗ trợ bản địa hoá theo khu vực (bao gồm cả ngôn ngữ RTL) cho phần giữ chỗ nhập văn bản, biểu trưng danh sách dự đoán và dự đoán địa điểm.
- Cải thiện khả năng hỗ trợ tiếp cận, bao gồm cả tính năng hỗ trợ trình đọc màn hình và tương tác bằng bàn phím.
- Tiện ích Tự động hoàn thành trả về lớp Địa điểm mới để đơn giản hoá việc xử lý đối tượng được trả về.
- Hỗ trợ tốt hơn cho thiết bị di động và màn hình nhỏ.
- Hiệu suất tốt hơn và giao diện đồ hoạ được cải thiện.
Thêm tiện ích Tự động hoàn thành
Bạn có thể thêm tiện ích Tự động hoàn thành vào một trang web hoặc bản đồ của Google. Tiện ích Tự động hoàn thành tạo một trường nhập văn bản, cung cấp thông tin dự đoán về địa điểm trong danh sách chọn của giao diện người dùng và trả về thông tin chi tiết về địa điểm để phản hồi lượt nhấp của người dùng thông qua trình nghe gmp-placeselect
. Phần này hướng dẫn bạn cách thêm tiện ích tự động hoàn thành vào một trang web hoặc bản đồ của Google.
Thêm tiện ích Tự động hoàn thành vào trang web
Để thêm tiện ích Tự động hoàn thành vào một trang web, hãy tạo một google.maps.places.PlaceAutocompleteElement
mới và thêm tiện ích đó vào trang như trong ví dụ sau:
TypeScript
// Request needed libraries. //@ts-ignore await google.maps.importLibrary("places") as google.maps.PlacesLibrary; // Create the input HTML element, and append it. //@ts-ignore const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement(); //@ts-ignore document.body.appendChild(placeAutocomplete);
JavaScript
// Request needed libraries. //@ts-ignore await google.maps.importLibrary("places"); // Create the input HTML element, and append it. //@ts-ignore const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement(); //@ts-ignore document.body.appendChild(placeAutocomplete);
Thêm tiện ích Tự động hoàn thành vào bản đồ
Để thêm tiện ích Tự động hoàn thành vào bản đồ, hãy tạo một thực thể google.maps.places.PlaceAutocompleteElement
mới, nối PlaceAutocompleteElement
vào div
rồi đẩy tiện ích đó vào bản đồ dưới dạng một thành phần điều khiển tuỳ chỉnh, như trong ví dụ sau:
TypeScript
//@ts-ignore const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement(); //@ts-ignore placeAutocomplete.id = 'place-autocomplete-input'; const card = document.getElementById('place-autocomplete-card') as HTMLElement; //@ts-ignore card.appendChild(placeAutocomplete); map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);
JavaScript
//@ts-ignore const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement(); //@ts-ignore placeAutocomplete.id = "place-autocomplete-input"; const card = document.getElementById("place-autocomplete-card"); //@ts-ignore card.appendChild(placeAutocomplete); map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);
Hạn chế cụm từ gợi ý của tính năng Tự động hoàn thành
Theo mặc định, tính năng Tự động hoàn thành địa điểm sẽ hiển thị tất cả các loại địa điểm, ưu tiên các địa điểm dự đoán gần vị trí của người dùng và tìm nạp tất cả các trường dữ liệu có sẵn cho địa điểm mà người dùng đã chọn. Đặt PlaceAutocompleteElementOptions để hiển thị các nội dung gợi ý phù hợp hơn bằng cách hạn chế hoặc thiên vị kết quả.
Việc hạn chế kết quả sẽ khiến tiện ích Tự động hoàn thành bỏ qua mọi kết quả nằm ngoài khu vực hạn chế. Một phương pháp phổ biến là hạn chế kết quả trong phạm vi bản đồ. Việc thiên vị kết quả sẽ khiến tiện ích Tự động hoàn thành hiển thị kết quả trong khu vực đã chỉ định, nhưng một số kết quả trùng khớp có thể nằm ngoài khu vực đó.
Nếu bạn không cung cấp giới hạn hoặc khung nhìn bản đồ nào, API sẽ cố gắng phát hiện vị trí của người dùng từ địa chỉ IP của họ và sẽ thiên vị kết quả cho vị trí đó. Đặt giới hạn bất cứ khi nào có thể. Nếu không, người dùng khác nhau có thể nhận được kết quả dự đoán khác nhau. Ngoài ra, để cải thiện khả năng dự đoán nói chung, điều quan trọng là bạn phải cung cấp một khung nhìn hợp lý, chẳng hạn như khung nhìn mà bạn đặt bằng cách kéo hoặc thu phóng trên bản đồ, hoặc khung nhìn do nhà phát triển đặt dựa trên vị trí và bán kính của thiết bị. Khi không có bán kính, 5 km được coi là bán kính mặc định hợp lý cho tính năng Tự động hoàn thành địa điểm. Đừng đặt khung nhìn có bán kính bằng 0 (một điểm), khung nhìn chỉ rộng vài mét (dưới 100 m) hoặc khung nhìn trải dài trên toàn cầu.
Hạn chế tìm kiếm địa điểm theo quốc gia
Để hạn chế tính năng tìm kiếm địa điểm ở một hoặc nhiều quốc gia cụ thể, hãy sử dụng thuộc tính componentRestrictions
để chỉ định(các) mã quốc gia như trong đoạn mã sau:
const pac = new google.maps.places.PlaceAutocompleteElement({ componentRestrictions: {country: ['us', 'au']}, });
Hạn chế tìm kiếm địa điểm trong ranh giới bản đồ
Để hạn chế phạm vi tìm kiếm địa điểm trong giới hạn của bản đồ, hãy sử dụng thuộc tính locationRestrictions
để thêm giới hạn, như minh hoạ trong đoạn mã sau:
const pac = new google.maps.places.PlaceAutocompleteElement({ locationRestriction: map.getBounds(), });
Khi hạn chế giới hạn bản đồ, hãy nhớ thêm trình nghe để cập nhật giới hạn khi chúng thay đổi:
map.addListener('bounds_changed', () => { autocomplete.locationRestriction = map.getBounds(); });
Để xoá locationRestriction
, hãy đặt thành null
.
Kết quả tìm kiếm địa điểm bị thiên vị
Chuyển kết quả tìm kiếm sang một vùng hình tròn bằng cách sử dụng thuộc tính locationBias
và truyền bán kính, như minh hoạ dưới đây:
const autocomplete = new google.maps.places.PlaceAutocompleteElement({ locationBias: {radius: 100, center: {lat: 50.064192, lng: -130.605469}}, });
Để xoá locationBias
, hãy đặt thành null
.
Hạn chế kết quả tìm kiếm địa điểm ở một số loại
Hạn chế kết quả tìm kiếm địa điểm ở một số loại địa điểm nhất định bằng cách sử dụng thuộc tính types
và chỉ định một hoặc nhiều loại, như minh hoạ dưới đây:
const autocomplete = new google.maps.places.PlaceAutocompleteElement({ types: ['establishment'], });
Để biết danh sách đầy đủ các loại được hỗ trợ, hãy xem Bảng 3: Các loại được hỗ trợ trong yêu cầu tự động hoàn thành địa điểm.
Nhận thông tin chi tiết về địa điểm
Để nhận thông tin chi tiết về địa điểm đã chọn, hãy thêm trình nghe gmp-placeselect
vào PlaceAutocompleteElement
, như trong ví dụ sau:
TypeScript
// Add the gmp-placeselect listener, and display the results. //@ts-ignore placeAutocomplete.addEventListener('gmp-placeselect', async ({ place }) => { await place.fetchFields({ fields: ['displayName', 'formattedAddress', 'location'] }); selectedPlaceTitle.textContent = 'Selected Place:'; selectedPlaceInfo.textContent = JSON.stringify( place.toJSON(), /* replacer */ null, /* space */ 2); });
JavaScript
// Add the gmp-placeselect listener, and display the results. //@ts-ignore placeAutocomplete.addEventListener("gmp-placeselect", async ({ place }) => { await place.fetchFields({ fields: ["displayName", "formattedAddress", "location"], }); selectedPlaceTitle.textContent = "Selected Place:"; selectedPlaceInfo.textContent = JSON.stringify( place.toJSON(), /* replacer */ null, /* space */ 2, ); });
Trong ví dụ trước, trình nghe sự kiện trả về một đối tượng của lớp Place.
Gọi place.fetchFields()
để lấy các trường dữ liệu Thông tin chi tiết về địa điểm cần thiết cho ứng dụng của bạn.
Trình nghe trong ví dụ tiếp theo yêu cầu thông tin về địa điểm và hiển thị thông tin đó trên bản đồ.
TypeScript
// Add the gmp-placeselect listener, and display the results on the map. //@ts-ignore placeAutocomplete.addEventListener('gmp-placeselect', async ({ place }) => { await place.fetchFields({ fields: ['displayName', 'formattedAddress', 'location'] }); // If the place has a geometry, then present it on a map. if (place.viewport) { map.fitBounds(place.viewport); } else { map.setCenter(place.location); map.setZoom(17); } let content = '<div id="infowindow-content">' + '<span id="place-displayname" class="title">' + place.displayName + '</span><br />' + '<span id="place-address">' + place.formattedAddress + '</span>' + '</div>'; updateInfoWindow(content, place.location); marker.position = place.location; });
JavaScript
// Add the gmp-placeselect listener, and display the results on the map. //@ts-ignore placeAutocomplete.addEventListener("gmp-placeselect", async ({ place }) => { await place.fetchFields({ fields: ["displayName", "formattedAddress", "location"], }); // If the place has a geometry, then present it on a map. if (place.viewport) { map.fitBounds(place.viewport); } else { map.setCenter(place.location); map.setZoom(17); } let content = '<div id="infowindow-content">' + '<span id="place-displayname" class="title">' + place.displayName + "</span><br />" + '<span id="place-address">' + place.formattedAddress + "</span>" + "</div>"; updateInfoWindow(content, place.location); marker.position = place.location; });
Bản đồ mẫu
Phần này chứa mã hoàn chỉnh cho các bản đồ mẫu xuất hiện trên trang này.
Phần tử tự động hoàn thành
Ví dụ này thêm một tiện ích Tự động hoàn thành vào một trang web và hiển thị kết quả cho từng vị trí đã chọn.
TypeScript
async function initMap(): Promise<void> { // Request needed libraries. //@ts-ignore await google.maps.importLibrary("places") as google.maps.PlacesLibrary; // Create the input HTML element, and append it. //@ts-ignore const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement(); //@ts-ignore document.body.appendChild(placeAutocomplete); // Inject HTML UI. const selectedPlaceTitle = document.createElement('p'); selectedPlaceTitle.textContent = ''; document.body.appendChild(selectedPlaceTitle); const selectedPlaceInfo = document.createElement('pre'); selectedPlaceInfo.textContent = ''; document.body.appendChild(selectedPlaceInfo); // Add the gmp-placeselect listener, and display the results. //@ts-ignore placeAutocomplete.addEventListener('gmp-placeselect', async ({ place }) => { await place.fetchFields({ fields: ['displayName', 'formattedAddress', 'location'] }); selectedPlaceTitle.textContent = 'Selected Place:'; selectedPlaceInfo.textContent = JSON.stringify( place.toJSON(), /* replacer */ null, /* space */ 2); }); } initMap();
JavaScript
async function initMap() { // Request needed libraries. //@ts-ignore await google.maps.importLibrary("places"); // Create the input HTML element, and append it. //@ts-ignore const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement(); //@ts-ignore document.body.appendChild(placeAutocomplete); // Inject HTML UI. const selectedPlaceTitle = document.createElement("p"); selectedPlaceTitle.textContent = ""; document.body.appendChild(selectedPlaceTitle); const selectedPlaceInfo = document.createElement("pre"); selectedPlaceInfo.textContent = ""; document.body.appendChild(selectedPlaceInfo); // Add the gmp-placeselect listener, and display the results. //@ts-ignore placeAutocomplete.addEventListener("gmp-placeselect", async ({ place }) => { await place.fetchFields({ fields: ["displayName", "formattedAddress", "location"], }); selectedPlaceTitle.textContent = "Selected Place:"; selectedPlaceInfo.textContent = JSON.stringify( place.toJSON(), /* replacer */ null, /* space */ 2, ); }); } initMap();
CSS
/* * Always set the map height explicitly to define the size of the div element * that contains the map. */ #map { height: 100%; } /* * Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; } p { font-family: Roboto, sans-serif; font-weight: bold; }
HTML
<html> <head> <title>Place Autocomplete element</title> <link rel="stylesheet" type="text/css" href="./style.css" /> <script type="module" src="./index.js"></script> </head> <body> <p style="font-family: roboto, sans-serif">Search for a place here:</p> <!-- 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: "beta"});</script> </body> </html>
Thử mẫu
Bản đồ tự động hoàn thành
Ví dụ này cho bạn biết cách thêm tiện ích Tự động hoàn thành vào bản đồ của Google.
TypeScript
let map: google.maps.Map; let marker: google.maps.marker.AdvancedMarkerElement; let infoWindow: google.maps.InfoWindow; async function initMap(): Promise<void> { // Request needed libraries. //@ts-ignore const [{ Map }, { AdvancedMarkerElement }] = await Promise.all([ google.maps.importLibrary("marker"), google.maps.importLibrary("places") ]); // Initialize the map. map = new google.maps.Map(document.getElementById('map') as HTMLElement, { center: { lat: 40.749933, lng: -73.98633 }, zoom: 13, mapId: '4504f8b37365c3d0', mapTypeControl: false, }); //@ts-ignore const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement(); //@ts-ignore placeAutocomplete.id = 'place-autocomplete-input'; const card = document.getElementById('place-autocomplete-card') as HTMLElement; //@ts-ignore card.appendChild(placeAutocomplete); map.controls[google.maps.ControlPosition.TOP_LEFT].push(card); // Create the marker and infowindow marker = new google.maps.marker.AdvancedMarkerElement({ map, }); infoWindow = new google.maps.InfoWindow({}); // Add the gmp-placeselect listener, and display the results on the map. //@ts-ignore placeAutocomplete.addEventListener('gmp-placeselect', async ({ place }) => { await place.fetchFields({ fields: ['displayName', 'formattedAddress', 'location'] }); // If the place has a geometry, then present it on a map. if (place.viewport) { map.fitBounds(place.viewport); } else { map.setCenter(place.location); map.setZoom(17); } let content = '<div id="infowindow-content">' + '<span id="place-displayname" class="title">' + place.displayName + '</span><br />' + '<span id="place-address">' + place.formattedAddress + '</span>' + '</div>'; updateInfoWindow(content, place.location); marker.position = place.location; }); } // Helper function to create an info window. function updateInfoWindow(content, center) { infoWindow.setContent(content); infoWindow.setPosition(center); infoWindow.open({ map, anchor: marker, shouldFocus: false, }); } initMap();
JavaScript
let map; let marker; let infoWindow; async function initMap() { // Request needed libraries. //@ts-ignore const [{ Map }, { AdvancedMarkerElement }] = await Promise.all([ google.maps.importLibrary("marker"), google.maps.importLibrary("places"), ]); // Initialize the map. map = new google.maps.Map(document.getElementById("map"), { center: { lat: 40.749933, lng: -73.98633 }, zoom: 13, mapId: "4504f8b37365c3d0", mapTypeControl: false, }); //@ts-ignore const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement(); //@ts-ignore placeAutocomplete.id = "place-autocomplete-input"; const card = document.getElementById("place-autocomplete-card"); //@ts-ignore card.appendChild(placeAutocomplete); map.controls[google.maps.ControlPosition.TOP_LEFT].push(card); // Create the marker and infowindow marker = new google.maps.marker.AdvancedMarkerElement({ map, }); infoWindow = new google.maps.InfoWindow({}); // Add the gmp-placeselect listener, and display the results on the map. //@ts-ignore placeAutocomplete.addEventListener("gmp-placeselect", async ({ place }) => { await place.fetchFields({ fields: ["displayName", "formattedAddress", "location"], }); // If the place has a geometry, then present it on a map. if (place.viewport) { map.fitBounds(place.viewport); } else { map.setCenter(place.location); map.setZoom(17); } let content = '<div id="infowindow-content">' + '<span id="place-displayname" class="title">' + place.displayName + "</span><br />" + '<span id="place-address">' + place.formattedAddress + "</span>" + "</div>"; updateInfoWindow(content, place.location); marker.position = place.location; }); } // Helper function to create an info window. function updateInfoWindow(content, center) { infoWindow.setContent(content); infoWindow.setPosition(center); infoWindow.open({ map, anchor: marker, shouldFocus: false, }); } initMap();
CSS
/* * Always set the map height explicitly to define the size of the div element * that contains the map. */ #map { height: 100%; } /* * Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; } #place-autocomplete-card { background-color: #fff; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; margin: 10px; padding: 5px; font-family: Roboto, sans-serif; font-size: large; font-weight: bold; } gmp-place-autocomplete { width: 300px; } #infowindow-content .title { font-weight: bold; } #map #infowindow-content { display: inline; }
HTML
<html> <head> <title>Place Autocomplete map</title> <link rel="stylesheet" type="text/css" href="./style.css" /> <script type="module" src="./index.js"></script> </head> <body> <div class="place-autocomplete-card" id="place-autocomplete-card"> <p>Search for a place here:</p> </div> <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: "beta"});</script> </body> </html>
Thử mẫu
Sử dụng thành phần Bộ chọn địa điểm
Thành phần bộ chọn địa điểm là một thành phần nhập văn bản cho phép người dùng cuối tìm kiếm một địa chỉ hoặc địa điểm cụ thể bằng tính năng tự động hoàn thành. Thư viện này là một phần của Thư viện thành phần mở rộng, một bộ thành phần web giúp nhà phát triển xây dựng bản đồ và các tính năng vị trí tốt hơn một cách nhanh chóng hơn.
Sử dụng trình định cấu hình bộ chọn địa điểm để tạo mã có thể nhúng cho thành phần bộ chọn địa điểm tuỳ chỉnh, sau đó xuất mã đó để sử dụng với các khung phổ biến như React và Angular hoặc không có khung nào cả.