You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Google Maps API拖拽标记时获取自动补全地址组件

Hey there, I see the issue you're facing. The autocomplete works great when searching, but when you drag the marker or click the map, the address fields don't update because there's no code handling those events to fetch the new address components. Let's fix that!

Here's what we need to do:

  • Make the marker draggable so users can move it around
  • Add event listeners for when the marker stops dragging and when the map is clicked
  • Use the geocoder to reverse-lookup the address from the new coordinates, then update all the address fields just like the autocomplete does

Here's your modified code with these changes:

<head> 
  <title>Place Autocomplete Address Form</title> 
  <meta name="viewport" content="initial-scale=1.0, user-scalable=no"> 
  <meta charset="utf-8"> 
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> 
  <link type="text/css" rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500"> 
  <style> 
    /* Always set the map height explicitly to define the size of the div * element that contains the map. */ 
    #map { height: 100%; } 
    /* Optional: Makes the sample page fill the window. */ 
    html, body { height: 100%; margin: 0; padding: 0; } 
    #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; } 
  </style> 
  <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA1BvEkX8v91LRu43HQe0-GNaHTVnoTSQs&libraries=places&callback=initMap" async defer></script> 
</head> 
<body> 
  <br><br> 
  <div id="locationField"> 
    <input id="autocomplete" placeholder="Enter your address" type="text"></input> 
  </div> 
  <table id="address"> 
    <tr> 
      <td class="label">Street address</td> 
      <td class="slimField"><input class="field" id="street_number" disabled="true" name="streetnumber"></input></td> 
      <td class="wideField" colspan="2"><input class="field" id="route" disabled="true" name="route"></input></td> 
    </tr> 
    <tr> 
      <td class="label">City</td> 
      <td class="wideField" colspan="3"><input class="field" id="locality" disabled="true" name="locality"></input></td> 
    </tr> 
    <tr> 
      <td class="label">State</td> 
      <td class="slimField"><input class="field" id="administrative_area_level_1" disabled="true" name="state" ></input></td> 
      <td class="label">Zip code</td> 
      <td class="wideField"><input class="field" id="postal_code" disabled="true" name="postal_code"></input></td> 
    </tr> 
    <tr> 
      <td class="label">Country</td> 
      <td class="wideField" colspan="3"><input class="field" id="country" disabled="true" name="country"></input></td> 
    </tr> 
  </table> 
  <div id="map" style="width: 50%; height: 250px;"></div> 
  <div id="infowindow-content"> 
    <img src="" width="16" height="16" id="place-icon"> 
    <span id="place-name" class="title"></span><br> 
    <span id="place-address"></span> 
  </div> 
  <script> 
    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' 
    }; 
    var input = document.getElementById('autocomplete'); 

    function initMap() { 
      var geocoder; 
      var autocomplete; 
      geocoder = new google.maps.Geocoder(); 

      var map = new google.maps.Map(document.getElementById('map'), { 
        center: {lat: -33.8688, lng: 151.2195}, 
        zoom: 13 
      }); 

      var card = document.getElementById('locationField'); 
      autocomplete = new google.maps.places.Autocomplete(input); 

      // Bind the map's bounds to the autocomplete object 
      autocomplete.bindTo('bounds', map); 

      var infowindow = new google.maps.InfoWindow(); 
      var infowindowContent = document.getElementById('infowindow-content'); 
      infowindow.setContent(infowindowContent); 

      // Create draggable marker 
      var marker = new google.maps.Marker({ 
        map: map, 
        anchorPoint: new google.maps.Point(0, -29), 
        draggable: true // Make marker draggable 
      }); 

      // Handle autocomplete place selection 
      autocomplete.addListener('place_changed', function() { 
        infowindow.close(); 
        var place = autocomplete.getPlace(); 

        if (!place.geometry) { 
          window.alert("No details available for input: '" + place.name + "'"); 
          return; 
        } 

        // If the place has a geometry, then present it on a map. 
        if (place.geometry.viewport) { 
          map.fitBounds(place.geometry.viewport); 
        } else { 
          map.setCenter(place.geometry.location); 
          map.setZoom(17); 
        } 
        marker.setPosition(place.geometry.location); 
        marker.setVisible(true); 

        // Fill in address fields from autocomplete place 
        fillInAddress(place); 
      }); 

      // Update address when marker is dragged 
      marker.addListener('dragend', function() { 
        updateAddressFromLatLng(this.getPosition()); 
      }); 

      // Update address when map is clicked 
      map.addListener('click', function(e) { 
        marker.setPosition(e.latLng); 
        updateAddressFromLatLng(e.latLng); 
      }); 

      // Function to fill address fields from place object 
      function fillInAddress(place) { 
        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; 
          } 
        } 

        // Update infowindow 
        infowindowContent.getElementById('place-name').textContent = place.name; 
        infowindowContent.getElementById('place-address').textContent = place.formatted_address; 
        infowindow.open(map, marker); 
      } 

      // Function to update address from LatLng using reverse geocoding 
      function updateAddressFromLatLng(latLng) { 
        geocoder.geocode({ 'location': latLng }, function(results, status) { 
          if (status === 'OK' && results[0]) { 
            // Update autocomplete input with full address 
            input.value = results[0].formatted_address; 

            // Clear existing fields 
            for (var component in componentForm) { 
              document.getElementById(component).value = ''; 
            } 

            // Fill address fields from geocode results 
            results[0].address_components.forEach(function(component) { 
              var componentType = component.types[0]; 
              if (componentForm[componentType]) { 
                var val = component[componentForm[componentType]]; 
                document.getElementById(componentType).value = val; 
              } 
            }); 

            // Update infowindow 
            infowindowContent.getElementById('place-name').textContent = results[0].name || results[0].formatted_address; 
            infowindowContent.getElementById('place-address').textContent = results[0].formatted_address; 
            infowindow.open(map, marker); 
          } else { 
            console.error('Geocode failed: ' + status); 
            window.alert('Could not retrieve address for this location.'); 
          } 
        }); 
      } 
    } 
  </script> 
</body>

Key Changes Explained:

  1. Draggable Marker: Added draggable: true to the marker initialization so users can move it.
  2. Event Listeners: Added listeners for dragend (when marker stops moving) and map click (to place marker at clicked location).
  3. Reverse Geocoding: The updateAddressFromLatLng function takes coordinates, uses the geocoder to get address components, and updates all form fields just like the autocomplete does.
  4. Consistent Updates: Ensures the autocomplete input field and infowindow also get updated when the marker is moved.

Now when you drag the marker or click anywhere on the map, all the address fields (street number, city, state, etc.) will automatically update to match the new location.

内容的提问来源于stack exchange,提问作者somesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:49:17