我使用以下代码来执行;"智能";使用Google Places API通过Geosearch自动完成:
var input = 'field_18';
google.maps.event.addDomListener(document.getElementById(input), 'keydown', function(event) {
if (event.keyCode === 13) {
event.preventDefault();
}
});
var ppx_autocomplete = new google.maps.places.Autocomplete((document.getElementById(input)), { types: ['geocode'] });
ppx_autocomplete.setFields(['geometry', 'formatted_address']);
google.maps.event.addListener(ppx_autocomplete, 'place_changed', function () {
var place = ppx_autocomplete.getPlace();
document.getElementById(input).value = place.formatted_address;
var lat = place.geometry.location.lat();
var lng = place.geometry.location.lng();
document.getElementById('pp_18_geocode').value = latlng;
});
很普通,很直率。
缺点是:自动完成从输入的前2或3个字母开始,导致向谷歌发出大量请求,从而导致我的API密钥消耗。
有没有任何方法可以限制请求的数量,例如,只在键入5个字母后发送请求,并且可能在一段延迟时间后发送,例如,当用户仍然键入时不发送请求。。。
您想要的可以完成,但您需要使用自动完成服务[1]而不是自动完成小部件[2]。这里有一个例子,它等待到输入第五个字符才发出请求,然后在每增加2个字符后发出一个请求。字符数可以在";在此处编辑参数";。您需要插入自己的API密钥。类似的例子在https://codepen.io/ecglover8/pen/ExPqdNd每3个字符执行一次。
由于您不会使用"自动完成"小部件,因此您需要自己处理会话令牌[3](未显示(。从价格的角度来看,你是否需要代币取决于你计划如何使用预测[4]。这个示例实际上使用预测中的Place ID生成地理编码API请求,并显示lat/long。
[1]https://developers.google.com/maps/documentation/javascript/places-autocomplete#place_autocomplete_service
[2]https://developers.google.com/maps/documentation/javascript/places-autocomplete#add-自动完成
[3]https://developers.google.com/maps/documentation/javascript/places-autocomplete#session_tokens
[4]https://developers.google.com/maps/documentation/places/web-service/usage-and-billing#ac-按请求
//declare constants
const ac = document.getElementById("ac");
const g = document.getElementById("geocoded");
const results = document.getElementById("results");
//listen for typing into input box
ac.addEventListener("input", ACRequest);
//show resulting predictions
const displayPredictions = function(predictions, status) {
results.innerHTML = "";
g.innerHTML = "";
if (status != google.maps.places.PlacesServiceStatus.OK) {
alert(status);
return;
}
predictions.forEach(prediction => {
let li = document.createElement("li");
li.appendChild(document.createTextNode(prediction.description));
li.dataset.placeid = prediction.place_id;
li.addEventListener("click", Geo)
results.appendChild(li);
});
let img = document.createElement("img");
img.setAttribute("src", "https://developers.google.com/maps/documentation/images/powered_by_google_on_white.png");
results.appendChild(img);
};
//make autocomplete request if input value length divisible by 3
function ACRequest() {
//edit params here
if ((ac.value.length > 4) && (ac.value.length % 2 == 1)) {
const service = new google.maps.places.AutocompleteService();
service.getPlacePredictions(
{
//here is where you can add bounds, componentrestrictions, types, etc
input: ac.value
}, displayPredictions
)
};
};
function Geo() {
console.log(this.getAttribute("data-placeid"));
const geocoder = new google.maps.Geocoder();
geocoder.geocode(
{
"placeId": this.getAttribute("data-placeid")
}, function(address, status) {
if (status == "OK") {
g.innerHTML = address[0].geometry.location
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
li {
border: 2px solid blue;
list-style: none;
margin: 2px;
padding: 2px;
}
li:hover {
border: 2px solid red;
}
.pac-card {
border-radius: 2px 0 0 2px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
box-sizing: border-box;
font-family: Roboto;
margin: 10px 10px 0 0;
outline: none;
}
.title {
background-color: #4D90FE;
color: #FFFFFF;
font-size: 25px;
font-weight: 500;
margin: 10px 0px;
padding: 6px 12px;
}
<div class="pac-card">
<div class="title">Autocomplete Makes Requests Every Three Characters</div>
<input id="ac" size="10" type="text" />
<ul id="results"></ul>
<p id="geocoded"></p>
</div>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY&libraries=places&v=weekly" async defer></script>