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 các dự đoán về địa điểm trong danh sách chọn trên 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ự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 một giao diện người dùng tự động hoàn thành hoàn chỉnh 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 phải bật "Places API (mới)" trên dự án Google Cloud của mình. Hãy xem phần Bắt đầu sử dụng để biết thông tin chi tiết.
Tính năng mới
Tính năng Place Autocomplete đã được cải thiện theo những cách sau:
- Giao diện người dùng của tiện ích Tự động hoàn thành hỗ trợ hoạt động 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à các dự đoán về địa điểm.
- Nâng cao 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ải thiện.
Thêm tiện ích Tự động hoàn thành
Tiện ích Tự động hoàn thành sẽ tạo một trường nhập văn bản, cung cấp các dự đoán về địa điểm trong danh sách chọn trên 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 bằng cách sử dụng trình nghe gmp-select
. Phần này hướng dẫn cách thêm một tiện ích tự động hoàn thành vào một trang web hoặc Google Maps.
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à nối tiện ích đó vào trang như trong ví dụ sau:
TypeScript
// Request needed libraries. 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. 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 đồ
Nếu địa chỉ thanh toán của bạn nằm bên ngoài Khu vực kinh tế Châu Âu (EEA), bạn cũng có thể sử dụng tiện ích Tự động hoàn thành với Google Maps.
Để thêm một 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
và đẩy thực thể đó lên bản đồ dưới dạng một chế độ kiểm soát 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'; placeAutocomplete.locationBias = center; 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'; placeAutocomplete.locationBias = center; 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ẽ trình bày tất cả các loại địa điểm, thiên về những 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 để trình bày các kết quả dự đoán 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ả 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 thường dùng là hạn chế kết quả trong phạm vi ranh giới trên bản đồ. Việc điều chỉnh kết quả giúp tiện ích Tự động hoàn thành hiển thị kết quả trong khu vực đượ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 bất kỳ ranh giới hoặc khung hiển thị 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ẽ điều chỉnh kết quả theo vị trí đó. Đặt ranh giới bất cứ khi nào có thể. Nếu không, những người dùng khác nhau có thể nhận được những dự đoán khác nhau. Ngoài ra, để cải thiện các dự đoán nói chung, bạn cần cung cấp một khung hiển thị hợp lý, chẳng hạn như khung hiển thị mà bạn đặt bằng cách di chuyển hoặc thu phóng trên bản đồ, hoặc khung hiển thị 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à giá trị mặc định hợp lý cho tính năng Tự động hoàn thành địa điểm. Không đặt khung hiển thị có bán kính bằng 0 (một điểm duy nhất), khung hiển thị chỉ rộng vài mét (dưới 100 m) hoặc khung hiển thị trải rộng trên toàn cầu.
Hạn chế tìm kiếm địa điểm theo quốc gia
Để giới hạn tìm kiếm địa điểm ở một hoặc nhiều quốc gia cụ thể, hãy dùng thuộc tính includedRegionCodes
để chỉ định(các) mã quốc gia như minh hoạ trong đoạn mã sau:
const pac = new google.maps.places.PlaceAutocompleteElement({ includedRegionCodes: ['us', 'au'], });
Hạn chế tìm kiếm địa điểm trong ranh giới trên bản đồ
Để hạn chế tìm kiếm địa điểm trong phạm vi của bản đồ, hãy dùng thuộc tính locationRestrictions
để thêm phạm vi, như minh hoạ trong đoạn mã sau:
const pac = new google.maps.places.PlaceAutocompleteElement({ locationRestriction: map.getBounds(), });
Khi hạn chế theo ranh giới bản đồ, hãy nhớ thêm một trình nghe để cập nhật ranh giới khi ranh giới 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 thiên vị
Làm lệch kết quả tìm kiếm địa điểm sang một khu vực 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ạ ở đâ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 đối với một số loại nhất định
Hạn chế kết quả tìm kiếm địa điểm đối với một số loại địa điểm nhất định bằng cách sử dụng thuộc tính includedPrimaryTypes
và chỉ định một hoặc nhiều loại, như minh hoạ ở đây:
const autocomplete = new google.maps.places.PlaceAutocompleteElement({ includedPrimaryTypes: ['establishment'], });
Để xem danh sách đầy đủ các loại được hỗ trợ, hãy xem Bảng A và B về loại đị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 cho địa điểm đã chọn, hãy thêm một trình nghe gmp-select
vào PlaceAutocompleteElement
, như trong ví dụ sau:
TypeScript
// Add the gmp-placeselect listener, and display the results. //@ts-ignore placeAutocomplete.addEventListener('gmp-select', async ({ placePrediction }) => { const place = placePrediction.toPlace(); 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-select', async ({ placePrediction }) => { const place = placePrediction.toPlace(); 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 thuộc lớp Place.
Gọi place.fetchFields()
để lấy các trường dữ liệu 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-select', async ({ placePrediction }) => { const place = placePrediction.toPlace(); 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-select', async ({ placePrediction }) => { const place = placePrediction.toPlace(); 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 địa điểm được chọn.
TypeScript
async function initMap(): Promise<void> { // Request needed libraries. 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-select', async ({ placePrediction }) => { const place = placePrediction.toPlace(); 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. 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-select', async ({ placePrediction }) => { const place = placePrediction.toPlace(); 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: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly"});</script> </body> </html>
Dùng thử mẫu
Bản đồ tự động hoàn thành
Ví dụ này cho bạn biết cách thêm một tiện ích Tự động hoàn thành vào một bản đồ Google.
TypeScript
let map: google.maps.Map; let marker: google.maps.marker.AdvancedMarkerElement; let infoWindow: google.maps.InfoWindow; let center = { lat: 40.749933, lng: -73.98633 }; // New York City 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, zoom: 13, mapId: '4504f8b37365c3d0', mapTypeControl: false, }); //@ts-ignore const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement(); //@ts-ignore placeAutocomplete.id = 'place-autocomplete-input'; placeAutocomplete.locationBias = center; 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-select', async ({ placePrediction }) => { const place = placePrediction.toPlace(); 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; let center = { lat: 40.749933, lng: -73.98633 }; // New York City 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, zoom: 13, mapId: '4504f8b37365c3d0', mapTypeControl: false, }); //@ts-ignore const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement(); //@ts-ignore placeAutocomplete.id = 'place-autocomplete-input'; placeAutocomplete.locationBias = center; 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-select', async ({ placePrediction }) => { const place = placePrediction.toPlace(); 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: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly"});</script> </body> </html>
Dùng 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 dữ liệu đầu vào 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. Đâ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.
Sử dụng cấu hình Bộ chọn địa điểm để tạo mã có thể nhúng cho một thành phần Bộ chọn địa điểm tuỳ chỉnh, sau đó xuất mã này để dùng với các khung phổ biến như React và Angular hoặc không dùng khung nào cả.