在HTML格式之前加载API javascript并抛出InvalidValueError

时间:2018-02-16 03:28:52

标签: javascript api google-places-api

我已设置Google Places API以在帐户注册页面上自动填写地址表单。 虽然我已经对它进行了测试并看到它正常工作,并且所有字段都已填充,但有时我会在控制台日志中获得以下内容。

InvalidValueError:不是HTMLInputElement的实例

发生这种情况时引用的代码行是

document.getElementById('autoCompleteCountry').addEventListener('change', setAutocompleteCountry);

我已经发现,当发生此错误时,在添加select元素之前,站点主体中正在执行自动完成功能。

我的脚本是

    var placeSearch;
var autocomplete;
var countryRestrict = {'country': '<?php echo strtolower($countryRestrict['countries_iso_code_2']); ?>'};
var componentForm = {
  street_number: 'short_name',
  route: 'long_name',
  locality: 'long_name',
  administrative_area_level_1: 'long_name',
  country: 'short_name',
  postal_code: 'short_name'
};
function initAutocomplete() {
  // Create the autocomplete object, restricting the search to geographical location types.
  autocomplete = new google.maps.places.Autocomplete(
          (document.getElementById('autocomplete')), {
            types: ['geocode'],
            componentRestrictions: countryRestrict
          }
  );
  // When the user selects an address from the dropdown, populate the address fields in the form.
  autocomplete.addListener('place_changed', fillInAddress);
  // Add a DOM event listener to react when the user selects a country.
  document.getElementById('autoCompleteCountry').addEventListener('change', setAutocompleteCountry);
}
// Set the country restriction based on user input.
function setAutocompleteCountry() {
  var country = document.getElementById('autoCompleteCountry').value;
  autocomplete.setComponentRestrictions({'country': country});
  clearResults();
}

function clearResults() {
  var results = document.getElementById('autocomplete');
  while (results.childNodes[0]) {
    results.removeChild(results.childNodes[0]);
  }
}

function fillInAddress() {
  // Get the place details from the autocomplete object.
  var place = autocomplete.getPlace();
  for (var component in componentForm) {
    document.getElementById(component).value = '';
    document.getElementById(component).disabled = false;
  }
  // Get each component of the address from the place details
  // and fill the corresponding field on the form.
  var countriesArray = <?php echo json_encode(gaa_countries()) ; ?>;
  for (var i = 0; i < place.address_components.length; i++) {
    var addressType = place.address_components[i].types[0];
    if (componentForm[addressType]) {
      var val = place.address_components[i][componentForm[addressType]];
      if (addressType == 'locality') {
        document.getElementById(addressType).value = val;
      } else if (addressType == 'postal_code') {
        document.getElementById(addressType).value = val;
      } else if (addressType == 'administrative_area_level_1') {
        document.getElementById(addressType).value = val;
      } else if (addressType == 'country') {
        for (var j = 0; j < countriesArray.length; j++) {
          var countries_iso_code_2 = countriesArray[j].countries_iso_code_2;
          if (countries_iso_code_2 == place.address_components[i][componentForm[addressType]]) {
            var countryId = countriesArray[j].countries_id;
            document.getElementById(addressType).value = countryId;
          }
        }
      } else if (addressType == 'street_number') {
        document.getElementById('route').value = val;
      } else if (addressType == 'route') {
        for (var j = 0; j < countriesArray.length; j++) {
          var countries_iso_code_2 = countriesArray[j].countries_iso_code_2;
          if ((countries_iso_code_2 == place.address_components[5]['short_name']) || (countries_iso_code_2 == place.address_components[6]['short_name'])) {
            var addressFormat = countriesArray[j].address_format_id;
          }
        }
        if ((addressFormat == 1) || (addressFormat == 2) || (addressFormat == 7)) {
          var streetName = place.address_components[i][componentForm[addressType]];
          var houseNumber = document.getElementById('route').value;
          document.getElementById('route').value = houseNumber + ' ' + streetName;
        } else if (addressFormat == 5) {
          var streetName = place.address_components[i][componentForm[addressType]];
          var houseNumber = document.getElementById('route').value;
          document.getElementById('route').value = streetName + ' ' + houseNumber;
        }
      }
    }
  }
  if (place.address_components != undefined) {
    $('.details_billing').slideDown();
    $('#billing_address_not_found').hide();
    $('#locationField').hide();
  }
}

// Bias the autocomplete object to the user's geographical location,
// as supplied by the browser's 'navigator.geolocation' object.
function geolocate() {
  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function (position) {
      var geolocation = {
        lat: position.coords.latitude,
        lng: position.coords.longitude
      };
      var circle = new google.maps.Circle({
        center: geolocation,
        radius: position.coords.accuracy
      });
      autocomplete.setBounds(circle.getBounds());
    });
  }
}

表单的HTML是

<div id="locationField">
<label class="inputLabel" for="autoCompleteCountry">Country:</label>
<select name="gaa_country_id" id="autoCompleteCountry" >
  <option value="">Please Choose Your Country</option>
  <option value="AU" selected="selected">Australia</option>
  <option value="NZ">New Zealand</option>
  <option value="US">United States</option>
</select>
<br />
<br class="clearBoth" />
<label class="inputLabel" for="autocomplete">Enter your address:</label>
<input type="text" name="GoogleAutoAddress" id="autocomplete" placeholder="Start typing to find your address" onFocus="geolocate()" />  <a href="#" id="billing_hide_detailed_address">Hide details</a>
<a href="#" id="billing_address_not_found">Address not found ?</a>
</div>
<div class="details_billing">
<label class="inputLabel" for="route">Street Address:</label>
<input type="text" name="street_address" size = "41" maxlength= "64" id="route" placeholder="*" required /><input type="hidden" name="house_no" size = "1" maxlength = "" id="street_number" placeholder="ENTRY_HOUSE_NO_TEXT" />
<br class="clearBoth" />
<input type="text" name="should_be_empty"  size="40" id="CAAS" style="visibility:hidden; display:none;" autocomplete="off" />
<label class="inputLabel" for="suburb">Address Line 2:</label>
<input type="text" name="suburb" size = "33" maxlength = "32" id="suburb" placeholder="" />
<br class="clearBoth" />
<label class="inputLabel" for="city">City:</label>
<input type="text" name="city" size = "33" maxlength = "32" id="locality" placeholder="*" required />
<br class="clearBoth" />
<label class="inputLabel" for="state" id="stateLabel">State/Province:</label>
<input type="text" name="state" value="" size = "33" maxlength = "32" id="administrative_area_level_1" placeholder="*" /><input type="hidden" name="zone_id" />
<br class="clearBoth" />
<label class="inputLabel" for="postcode">Post/Zip Code:</label>
<input type="text" name="postcode" size = "11" maxlength = "10" id="postal_code" placeholder="*" required />
</div>

我尝试将功能包装在

$(window).load(function(){
  .....
});

但这只会导致

的另一条错误消息

未捕获Lb {消息:“initAutocomplete不是函数”,名称:“InvalidValueError”,堆栈:“错误↵新Lb(https://maps.googleapis.com/m ... libraries = places&amp; callback = initAutocomplete:151:59”}

我假设是因为

而被触发
<script src="https://maps.googleapis.com/maps/api/js?key=<?php echo GOOGLE_ADDRESS_API_KEY; ?>&libraries=places&callback=initAutocomplete" async defer></script>

在函数之前被调用,因此没有找到它期望的内容。

我对解决此问题的正确方法感到有点失落。 有什么建议吗?

0 个答案:

没有答案