从Google地方信息中选择值后,防止输入框出现模糊

时间:2018-11-02 17:19:58

标签: javascript html5 google-maps-api-3

当用户使用鼠标来选择Google地方信息API提供的城市/州的建议时,我想防止焦点从输入字段转移。这样,当用户单击“ Tab”时,焦点可以正确地移至下一个明显的输入字段。但是当用户选择(使用鼠标)Google Places API中的Google自动完成功能建议的值时,我无法阻止onblur事件的发生。使用键盘选择值时不会发生此问题。这是我的代码-感谢您对解决此问题的一些帮助,因为我对Google API代码的操作不太熟悉。

这是我的HTML代码:

<div class="col-md-4 col-sm-12 col-xs-12">
  <div class="form-group">
    <input gp-gac="{ types: ['(cities)'],  componentRestrictions: { country: 'US' }}" class="form-control"
      ng-model="home_ctrl.location"
      gp-components="{ locality: 'long_name', administrative_area_level_1: 'short_name' }"
      gp-callback="home_ctrl.gpSearchCb(result, place)"
      vs-city="home_ctrl.city"
      vs-state="home_ctrl.state"
      placeholder="City, State"
      id="txtCity">
  </div>
</div>

这是在Google Places API上调用的javascript代码:

(function() {
  'use strict'

  var gpGac = function() {
    return {
      restrict: 'A',
      require: '?ngModel',
      scope: {
        gpGac: '=',
        gpOptions: '=?',
        gpComponents: '=?',
        gpCity: '=?',
        gpState: '=?',
        gpZip: '=?',
        gpCallback: '&?',
      },
      link: {
        pre: function(scope, element, attributes, modelCtrl) {
          var autocomplete = new google.maps.places.Autocomplete(
              element[0],
              scope.gpGac,
            ),
            options = scope.gpOptions || {submitOnEnter: true},
            itemSelected

          scope.gpComponents = scope.gpComponents || {
            locality: 'long_name',
            sublocality: 'long_name',
            administrative_area_level_1: 'short_name',
            neighborhood: 'long_name',
            postal_code: 'short_name',
          }
          console.log(
            'scope.gpComponents: ' + JSON.stringify(scope.gpComponents),
          )
          var autocompleteListener = autocomplete.addListener(
            'place_changed',
            function() {
              var place = this.getPlace(),
                result = {}

              if (place.address_components) {
                place.address_components.forEach(function(addrComp) {
                  addrComp.types.forEach(function(type) {
                    if (scope.gpComponents && scope.gpComponents[type]) {
                      result[type] = addrComp[scope.gpComponents[type]]
                    }
                  })
                })

                scope.gpState = result.administrative_area_level_1
                if (result.locality && isOnDisplay(result.locality)) {
                  scope.gpCity = result.city = result.locality
                }
                if (result.sublocality && isOnDisplay(result.sublocality)) {
                  scope.gpCity = result.city = result.sublocality
                }
                if (result.neighborhood && isOnDisplay(result.neighborhood)) {
                  scope.gpCity = result.city = result.neighborhood
                }
                scope.gpZip = result.postal_code

                // check if it's displayed on input
                function isOnDisplay(addrComp) {
                  return place.formatted_address.search(addrComp) > -1
                }

                scope.$apply(function() {
                  if (modelCtrl) {
                    modelCtrl.$setViewValue(
                      result[options.display]
                        ? result[options.display]
                        : place.formatted_address,
                    )
                  } else {
                    element.val(
                      result[options.display]
                        ? result[options.display]
                        : place.formatted_address,
                    )
                  }
                  if (scope.gpCallback) {
                    scope.gpCallback({result: result, place: place})
                  }
                  if (modelCtrl) {
                    modelCtrl.$render()
                  }
                })
              }
            },
          )

          var enterKeydownListener = google.maps.event.addDomListener(
            element[0],
            'keydown',
            function(e) {
              if (e.keyCode === 13) {
                if (!options.submitOnEnter && itemSelected) {
                  e.preventDefault()
                  itemSelected = !itemSelected
                }
              }
            },
          )
          var enterKeyupListener = google.maps.event.addDomListener(
            element[0],
            'keyup',
            function(e) {
              if (e.keyCode === 38 || e.keyCode === 40) {
                itemSelected = angular
                  .element(document)
                  .find('.pac-item-selected').length
              }
            },
          )

          element.on('$destroy', function() {
            autocompleteListener.remove()
            enterKeydownListener.remove()
            enterKeyupListener.remove()
            autocomplete.unbindAll()
          })
        },
        post: function(scope, element, attributes, modelCtrl) {},
      },
    }
  }

  angular.module('routerApp').directive('gpGac', ['$rootScope', gpGac])
})()

1 个答案:

答案 0 :(得分:0)

解决方案在于对控制html的Javascript文件(而不是调用Google API的文件)进行以下更改。在正确的javascript文件中,将以下行添加到gpSearchCb函数的末尾:

$('#txtCity').focus()

,并在使用鼠标进行选择后将焦点保持在正确的输入字段中。