【问题标题】:Events other than 'place_changed' for Google Maps AutocompleteGoogle 地图自动填充的“place_changed”以外的事件
【发布时间】:2015-11-18 12:13:30
【问题描述】:

我有一个应用程序当前在 place_changed 上正确触发。

但是,当用户选择自动完成条目以及在没有自动完成帮助的情况下自行输入文本时,我希望分支搜索的行为有所不同。

我应该使用哪种事件侦听器来区分?我找不到关于 Google 地图自动完成的其他事件的任何文档。

我现在拥有的:

var gmaps = new google.maps.places.Autocomplete($("#searchproperties").get(0), 
{ types: ['geocode'], componentRestrictions: {country: 'us'} });

google.maps.event.addListener(gmaps, 'place_changed', function () {
    //FIRE SEARCH
});

【问题讨论】:

    标签: javascript jquery google-maps google-maps-api-3 autocomplete


    【解决方案1】:

    在 Google Maps Javascript API v3 中,google.maps.places.Autocomplete classplace_changed 仅记录了一个事件

    您可以为其添加标准 HTML 事件侦听器(不确定这是否会影响自动完成功能)。

    【讨论】:

    • 我遇到的问题是 blur 和 change 事件在 Google place_changed 事件之前触发。这使得很难知道实际发生了什么。
    • @nw。你能解决你的问题吗?我也有同样的问题。
    • 我想 OP 的问题可以理解为 “我应该使用什么 [...] 来进行区分?”,在这种情况下,这并没有提供完全解决。
    【解决方案2】:

    这归结为检查您是否收到place.geometry 对象,如their official example 所示。就这么简单!

    function initialize() {
    
      var ac = new google.maps.places.Autocomplete(
        (document.getElementById('autocomplete')), {
          types: ['geocode']
        });
    
      ac.addListener('place_changed', function() {
    
        var place = ac.getPlace();
    
        if (!place.geometry) {
          // User entered the name of a Place that was not suggested and
          // pressed the Enter key, or the Place Details request failed.
          // Do anything you like with what was entered in the ac field.
          console.log('You entered: ' + place.name);
          return;
        }
    
        console.log('You selected: ' + place.formatted_address);
      });
    }
    
    initialize();
    #autocomplete {
      width: 300px;
    }
    <input id="autocomplete" placeholder="Enter your address" type="text"></input>
    <script src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>

    【讨论】:

      【解决方案3】:

      如果您添加自己的输入处理程序(例如在用户输入自己的文本后捕获 CR),自动完成和您的函数可能会背靠背调用您的方法。我的解决方案是使用油门来避免重复调用:

      $('#sell_address_input').keyup(function(e){ if(e.keyCode==13){throttle(addressEntered(),1000)}});
      

      ....

      function throttle(callback, limit) {
          var wait = false;             // Initially, we're not waiting
          return function () {          // We return a throttled function
              if (!wait) 
              {                         // If we're not waiting
                callback.call();        // Execute users function
                wait = true;            // Prevent future invocations
                setTimeout(function () 
                {                       // After a period of time
                  wait = false;         // And allow future invocations
                }, limit);
              }
          }
      }
      

      【讨论】:

        【解决方案4】:

        (更新答案 - 2018 年 10 月 18 日th UTC)

        place_changeddocumentation 说:

        如果用户输入了控件未建议的地点名称并按 Enter 键,或者如果地点详细信息请求 失败,PlaceResult 在 name 中包含用户输入 属性,未定义其他属性

        所以(正如我在评论中提到的),我们可以检查属性name 是否是通过Autocomplete.getPlace() 检索到的PlaceResult 对象中的only 属性。查看并尝试下面的代码 sn-p:

        (如果 API 密钥不起作用,请使用 your own。)

        var gmaps = new google.maps.places.Autocomplete($("#searchproperties").get(0), 
        { types: ['geocode'], componentRestrictions: {country: 'us'} });
        
        google.maps.event.addListener(gmaps, 'place_changed', function () {
          var place = gmaps.getPlace(),
            has_name = ( place && undefined !== place.name ),
            count = 0;
        
          // Iterates through `place` and see if it has other props.
          $.each( place || {}, function(){
            if ( count > 1 ) {
              // No need to count all; so let's break the iteration.
              return false;
            }
            count++;
          });
        
          if ( has_name && count < 2 ) {
            $('#test').html( 'You didn\'t make a selection and typed: ' + place.name );
          } else {
            $('#test').html( 'You selected: ' + place.formatted_address );
          }
        });
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBMPpy3betC_QCBJtc3sC4BtEIYo4OYtPU&libraries=places"></script>
        
        <input id="searchproperties" placeholder="Search places">
        <div id="test"></div>

        【讨论】:

        • 您绝对不需要所有这些...有关详细信息,请参阅我的答案。
        • @MrUpsidown 至少,文档确实说,如果用户没有从找到的建议地点(如果有)中明确选择,name 属性将是用户输入的关键字自动完成字段。这就是答案的重点。我们还可以简单地检查place 是否具有name 作为 only 属性(如文档所述;因此我检查了undefined === place.formatted_address),如果是,那么这是手动“选择” ",假设请求成功。
        • 当然,这是您答案的有效部分。为什么他们检查place.geometry 而不是另一个属性没有在任何地方解释afaik 但我相信一个有效的地方总是 有几何形状,而其他参数可能会丢失(这是我的解释)。在任何情况下,您的代码似乎都可以工作,但您可以用更少的代码实现同样的效果;)
        • 是的,你是对的。我确实看到了geometry 和所有其他可能的属性,但我想我专注于“如果存在formatted_address,那么它不是手动选择或失败的请求”。 =) 无论如何,感谢您的编辑,尽管我故意不包括它,因为答案中已经有相同的链接。
        • 其实,谢谢@MrUpsidown。我更新了答案。希望它会帮助某人。 ;)
        【解决方案5】:

        这是一个相当古老的问题,但我提出的解决方案可能比我在这里阅读的要简单得多。

        “place_changed”事件仅在用户实际从 Google 列表中选择建议时触发。

        所以只要用户没有选择建议,就可以认为输入中输入的文字不是google的place结果。

        从这里,您可以将“place-changed”视为一种“点击”事件,使用布尔值来存储当前状态

        function initializeAutocomplete(id) {  
            var element = document.getElementById(id);    
            if (element) {    
                var autocomplete = new google.maps.places.Autocomplete(element, { types: ['geocode','establishment'], componentRestrictions: {country: ['fr']} });
                google.maps.event.addListener(autocomplete, 'place_changed', function(){
                    var place = this.getPlace();
                    console.log("A result from "+id+" was clicked !");
                    for (var i in place.address_components) {    
                        var component = place.address_components[i];    
                        for (var j in component.types) {  
                            var type_element = document.getElementById(component.types[j]);      
                            if (type_element) {        
                                type_element.value = component.long_name;
                            }    
                        }  
                    }               
                });         
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2016-08-28
          • 2012-01-27
          • 1970-01-01
          • 2018-03-30
          • 2016-11-08
          • 2011-05-02
          • 2015-01-23
          • 2012-04-27
          • 2012-09-30
          相关资源
          最近更新 更多