Google 地图 API 自动完成搜索但不选择下拉列表

9
我正在使用Google Maps API和Autocomplete搜索功能。目前,您必须开始输入位置(城市、州、邮编等),然后从下拉菜单中选择结果,地图才能以该位置为中心。但是,我希望将其设置得更加完善,如果有人只输入了城市或州并按下“enter”键,而没有选择自动完成的结果,它仍然可以正常工作。例如,如果有人只输入了“纽约”,并在下拉列表中未选择任何结果,它仍将居中显示在纽约。
我假设这可以通过从自动完成下拉列表中抓取第一个结果来实现,如果没有手动选择的话。
我已经为表单提交添加了事件侦听器,但不确定如何将第一个结果传递给“place”变量。
以下是我的代码:
function searchBar(map) {
    var input = document.getElementById('search-input');
    var searchform = document.getElementById('search-form');
    var place;
    var options = {componentRestrictions: {country: 'us'}};
    var autocomplete = new google.maps.places.Autocomplete(input, options);

    //Add listener to detect autocomplete selection
    google.maps.event.addListener(autocomplete, 'place_changed', function () {
        place = autocomplete.getPlace();
        center = new google.maps.LatLng(place.geometry.location.lat(),place.geometry.location.lng());
        map.setCenter(center);
        map.setZoom(5);
    });

    //Add listener to search
    searchform.addEventListener('submit', function() {
        center = new google.maps.LatLng(place.geometry.location.lat(),place.geometry.location.lng());
        map.setCenter(center);
        map.setZoom(5);
    });

    //Reset the inpout box on click
    input.addEventListener('click', function(){
        input.value = "";
    });
};

以下是一个JSFiddle,供您进行实验。

3个回答

19

没有实现一种直接访问下拉列表中位置的方法。基本上,您在下拉列表中看到的不是位置,而只是预测。选择一个预测后,将加载预测的详细信息。

因此,您必须以编程方式选择一个预测。

如何实现:

除了点击预测之外,另一种方法是使用向下键,键码为40。API 侦听输入框的 keydown 事件。

因此,当您按回车键时:

  1. 触发带有键码40(向下)的 keydown
  2. 触发带有键码13(回车)的 keydown

  3. google.maps.event.addDomListener(input,'keydown',function(e){
             if(e.keyCode===13 && !e.triggered){ 
       google.maps.event.trigger(this,'keydown',{keyCode:40}) 
       google.maps.event.trigger(this,'keydown',{keyCode:13,triggered:true}) 
     }
    });
    

注意:为了避免 enter 键的无限循环,我添加了一个自定义属性 triggered,因此可以在函数内部绕过触发的键按下事件。

演示:http://jsfiddle.net/4nr4tdwz/1/


1
毫无疑问,这是我在任何线程中找到的最好、最聪明的解决方案。非常棒地发掘了这个技巧! - Andreas Galster
如何在按下回车键时阻止默认表单提交?我尝试在 if(e.keyCode===13 && !e.triggered){ 中添加 return false,但似乎没有任何作用。 - MAX POWER
在我的示例(请参见 fiddle)中,可以通过设置 form-action(为javascript:void(0))来实现。 - Dr.Molle

2
我添加了一个筛选器,以避免在用户已经从自动完成中选择任何结果时触发按键按下事件:
google.maps.event.addDomListener(input,'keydown',function(e){
    if(e.keyCode===13 && $('.pac-item-selected').length == 0 && !e.triggered){ 
    google.maps.event.trigger(this,'keydown',{keyCode:40}) 
    google.maps.event.trigger(this,'keydown',{keyCode:13,triggered:true}) 
  }
});

0

编程中用于通过代码设置初始/默认位置的辅助函数 - 例如从地理位置 API 中获得。

    var triggerLocation = function(autocompleteInput, addressString) {
    var $locationInput = $(autocompleteInput).val(addressString).trigger('focus');
    var maxTries = 500;

    var autocompleteSelectionInterval = setInterval(function() {
        if (!--maxTries) {
            clearInterval(autocompleteSelectionInterval);
        }

        if ($('.pac-container .pac-item').length) {
            google.maps.event.trigger($locationInput[0], 'keydown', {
                keyCode : 40
            });

            google.maps.event.trigger($locationInput[0], 'keydown', {
                keyCode : 13
            });

            clearInterval(autocompleteSelectionInterval);
        }
    }, 10);
};

例子:

var autocomplete = new google.maps.places.Autocomplete($('#location')[0]);
triggerLocation('#location', 'New York');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接