在同一 html 页面谷歌地图上使用 initMap 和 initAutocomplete [英] Using initMap and initAutocomplete on same html page google maps

查看:11
本文介绍了在同一 html 页面谷歌地图上使用 initMap 和 initAutocomplete的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个网页,我想在其中使用地点自动完成功能以及带有标记的谷歌地图.用户可以就地自动完成搜索地址.标记的经纬度数据来自 DB,这不会改变.问题要么是地图有效,要么是地方自动完成,但不能两者兼而有之,问题与回调有关.

从谷歌文档中,我已经在单独的 API 调用中包含了这两个回调:

<script src="https://maps.googleapis.com/maps/api/js?key=[API KEY]&signed_in=true&libraries=places&callback=initAutocomplete"异步延迟></脚本><script async defer src="https://maps.googleapis.com/maps/api/js?key=[API KEY]&callback=initMap"></script>

但这会在控制台上引发错误,并且没有任何效果.

<块引用>

错误:您在此页面上多次包含 Google Maps API.这可能会导致意外错误.

我的问题是:如何将多个回调传递给 Google API?

解决方案

您不能添加多个回调(并且不应多次包含 API).将所有代码放在一个回调中.

<script src="https://maps.googleapis.com/maps/api/js?key=[API KEY]&signed_in=true&libraries=places&callback=initialize"异步延迟></脚本>函数初始化(){initMap();initAutoComplete();}

或查看文档中的此示例

function initialize() {initMap();初始化自动完成();}var 地图,标记;函数 initMap() {map = new google.maps.Map(document.getElementById('map'), {中央: {纬度:-34.397,液化石油气:150.644},变焦:8});}//此示例使用自动完成功能显示地址表单//帮助用户填写信息的 Google Places API.//此示例需要 Places 库.包括图书馆=地方//首次加载 API 时的参数.例如://<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places">var placeSearch,自动完成;var componentForm = {street_number: 'short_name',路线:'long_name',地点:'long_name',行政区域_级别_1:'short_name',国家:'long_name',postal_code: 'short_name'};函数 initAutocomplete() {//创建自动完成对象,将搜索限制为地理//位置类型.自动完成 = 新的 google.maps.places.Autocomplete(/** @type {!HTMLInputElement} */(document.getElementById('autocomplete')), {类型:['地理编码']});//当用户从下拉列表中选择一个地址时,填充该地址//表单中的字段.autocomplete.addListener('place_changed', fillInAddress);}函数 fillInAddress() {//从自动完成对象中获取地点详细信息.var place = autocomplete.getPlace();如果(地方.几何.视口){map.fitBounds(place.geometry.viewport);} 别的 {map.setCenter(place.geometry.location);地图.setZoom(17);//为什么是 17?因为它看起来不错.}如果(!标记){标记 = 新的 google.maps.Marker({地图:地图,锚点:新的 google.maps.Point(0, -29)});} else 标记.setMap(null);标记.setOptions({位置:place.geometry.location,地图:地图});for(componentForm 中的 var 组件){document.getElementById(component).value = '';document.getElementById(component).disabled = false;}//从地点详情中获取地址的各个组成部分//并填写表单上的相应字段.for (var i = 0; i < place.address_components.length; i++) {var addressType = place.address_components[i].types[0];如果(组件形式[地址类型]){var val = place.address_components[i][componentForm[addressType]];document.getElementById(addressType).value = val;}}}//将自动完成对象偏向用户的地理位置,//由浏览器的navigator.geolocation"对象提供.功能地理定位(){如果(navigator.geolocation){navigator.geolocation.getCurrentPosition(function(position) {var 地理位置 = {纬度:位置坐标.纬度,lng: position.coords.longitude};var circle = new google.maps.Circle({中心:地理位置,半径:position.coords.accuracy});autocomplete.setBounds(circle.getBounds());});}}

html,身体 {高度:100%;边距:0;填充:0;}#地图 {高度:100%;}#locationField,#控制{位置:相对;宽度:480px;}#自动完成{位置:绝对;顶部:0px;左:0px;宽度:99%;}.标签 {文本对齐:右;字体粗细:粗体;宽度:100px;颜色:#303030;}#地址 {边框:1px 实心 #000090;背景色:#f0f0ff;宽度:480px;填充右:2px;}#地址 td {字体大小:10pt;}.场地 {宽度:99%;}.slimField {宽度:80px;}.wideField {宽度:200px;}#locationField {高度:20px;底边距:2px;}

<input id="autocomplete" placeholder="输入您的地址" onFocus="geolocate()" type="text"/>

<table id="地址"><tr><td class="label">街道地址</td><td class="slimField"><input class="field" id="street_number" disabled="true"/></td><td class="wideField" colspan="2"><input class="field" id="route" disabled="true"/></td></tr><tr><td class="label">城市</td><td class="wideField" colspan="3"><input class="field" id="locality" disabled="true"/></td></tr><tr><td class="label">State</td><td class="slimField"><input class="field" id="administrative_area_level_1" disabled="true"/></td><td class="label">邮政编码</td><td class="wideField"><input class="field" id="postal_code" disabled="true"/></td></tr><tr><td class="label">国家</td><td class="wideField" colspan="3"><input class="field" id="country" disabled="true"/></td></tr><div id="地图"></div><script src="https://maps.googleapis.com/maps/api/js?libraries=places&callback=initialize&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"延迟></script>

I have a webpage where I would like to use both place autocomplete as well as google map with marker. User can search for an address in place autocomplete. Lat-long data for marker comes from DB and this doesn't change. The problem is either map works or place autocomplete, but not both, and the issue is related to callbacks.

From google docs, I've included both callbacks in separate API calls:

<script src="https://maps.googleapis.com/maps/api/js?key=[API KEY]&signed_in=true&libraries=places&callback=initAutocomplete" async defer></script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=[API KEY]&callback=initMap"></script>

But this throws error on console, and nothing works.

Error: You have included the Google Maps API multiple times on this page. This may cause unexpected errors.

My question is: How multiple callbacks can be passed to Google API?

解决方案

You can't add multiple callbacks (and you shouldn't include the API more than once). Put all the code in a single callback.

<script src="https://maps.googleapis.com/maps/api/js?key=[API KEY]&signed_in=true&libraries=places&callback=initialize" async defer></script>

function initialize() {
   initMap();
   initAutoComplete();
}

or see this example in the documentation

function initialize() {
  initMap();
  initAutocomplete();
}
var map, marker;

function initMap() {
    map = new google.maps.Map(document.getElementById('map'), {
      center: {
        lat: -34.397,
        lng: 150.644
      },
      zoom: 8
    });
  }
  // This example displays an address form, using the autocomplete feature
  // of the Google Places API to help users fill in the information.

// This example requires the Places library. Include the libraries=places
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places">

var placeSearch, autocomplete;
var componentForm = {
  street_number: 'short_name',
  route: 'long_name',
  locality: 'long_name',
  administrative_area_level_1: 'short_name',
  country: 'long_name',
  postal_code: 'short_name'
};

function initAutocomplete() {
  // Create the autocomplete object, restricting the search to geographical
  // location types.
  autocomplete = new google.maps.places.Autocomplete(
    /** @type {!HTMLInputElement} */
    (document.getElementById('autocomplete')), {
      types: ['geocode']
    });

  // When the user selects an address from the dropdown, populate the address
  // fields in the form.
  autocomplete.addListener('place_changed', fillInAddress);
}

function fillInAddress() {
  // Get the place details from the autocomplete object.
  var place = autocomplete.getPlace();
  if (place.geometry.viewport) {
    map.fitBounds(place.geometry.viewport);
  } else {
    map.setCenter(place.geometry.location);
    map.setZoom(17); // Why 17? Because it looks good.
  }
  if (!marker) {
    marker = new google.maps.Marker({
      map: map,
      anchorPoint: new google.maps.Point(0, -29)
    });
  } else marker.setMap(null);
  marker.setOptions({
    position: place.geometry.location,
    map: map
  });

  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.
  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]];
      document.getElementById(addressType).value = val;
    }
  }
}

// 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,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}
#map {
  height: 100%;
}
#locationField,
#controls {
  position: relative;
  width: 480px;
}
#autocomplete {
  position: absolute;
  top: 0px;
  left: 0px;
  width: 99%;
}
.label {
  text-align: right;
  font-weight: bold;
  width: 100px;
  color: #303030;
}
#address {
  border: 1px solid #000090;
  background-color: #f0f0ff;
  width: 480px;
  padding-right: 2px;
}
#address td {
  font-size: 10pt;
}
.field {
  width: 99%;
}
.slimField {
  width: 80px;
}
.wideField {
  width: 200px;
}
#locationField {
  height: 20px;
  margin-bottom: 2px;
}

<div id="locationField">
  <input id="autocomplete" placeholder="Enter your address" onFocus="geolocate()" type="text" />
</div>

<table id="address">
  <tr>
    <td class="label">Street address</td>
    <td class="slimField">
      <input class="field" id="street_number" disabled="true" />
    </td>
    <td class="wideField" colspan="2">
      <input class="field" id="route" disabled="true" />
    </td>
  </tr>
  <tr>
    <td class="label">City</td>
    <td class="wideField" colspan="3">
      <input class="field" id="locality" disabled="true" />
    </td>
  </tr>
  <tr>
    <td class="label">State</td>
    <td class="slimField">
      <input class="field" id="administrative_area_level_1" disabled="true" />
    </td>
    <td class="label">Zip code</td>
    <td class="wideField">
      <input class="field" id="postal_code" disabled="true" />
    </td>
  </tr>
  <tr>
    <td class="label">Country</td>
    <td class="wideField" colspan="3">
      <input class="field" id="country" disabled="true" />
    </td>
  </tr>
</table>
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?libraries=places&callback=initialize&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk" defer></script>

这篇关于在同一 html 页面谷歌地图上使用 initMap 和 initAutocomplete的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆