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

Google Maps API地址自动补全:州/省下拉框无法选中问题排查

问题分析与修复

核心问题

你的代码中,地址自动补全的place_changed事件处理逻辑顺序错误:先设置了州/省的值,再处理国家并触发change事件。而国家的change事件会清空州下拉框并重新生成对应国家的州/省选项,导致之前设置的州值被覆盖,无法在新生成的下拉框中选中对应选项。

修复方案

  1. 遍历地址组件时,先收集所有需要填充的地址数据(州、国家、城市等),而非边遍历边修改DOM
  2. 优先设置国家值并触发change事件,让下拉框加载对应国家的州/省选项
  3. 最后再设置州/省及其他字段的值,此时下拉框已有对应选项,就能正确选中

修改后的完整代码

<!DOCTYPE html>
<html>

<head>
    <title>Google Places API Autocomplete</title>
    <script
        src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places"></script>
    <script>
        function initialize() {
            var senderStreetInput = document.getElementById('sender_street');
            var senderApartmentInput = document.getElementById('sender_apartment');
            var senderCityInput = document.getElementById('sender_city');
            var senderStateSelect = document.getElementById('sender_state');
            var senderPostalCodeInput = document.getElementById('sender_postal_code');
            var senderCountrySelect = document.getElementById('sender_country');
            var senderStreetAutocomplete = new google.maps.places.Autocomplete(senderStreetInput, {
                types: ['address']
            });
            var senderApartmentAutocomplete = new google.maps.places.Autocomplete(senderApartmentInput, {
                types: ['address']
            });
            var senderCityAutocomplete = new google.maps.places.Autocomplete(senderCityInput, {
                types: ['(cities)']
            });
            senderCountrySelect.addEventListener('change', function () {
                var country = this.value;
                senderStateSelect.innerHTML = '';
                var regions = [];
                if (country === 'Canada') {
                    regions = [
                        'Alberta', 'British Columbia', 'Manitoba', 'New Brunswick', 'Newfoundland and Labrador',
                        'Northwest Territories', 'Nova Scotia', 'Nunavut', 'Ontario', 'Prince Edward Island',
                        'Quebec', 'Saskatchewan', 'Yukon'
                    ];
                } else if (country === 'United States') {
                    regions = [
                        'Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut',
                        'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa',
                        'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan',
                        'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire',
                        'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota', 'Ohio',
                        'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota',
                        'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia',
                        'Wisconsin', 'Wyoming'
                    ];
                }
                var option = document.createElement('option');
                option.value = '';
                option.textContent = 'Select a state/province';
                senderStateSelect.appendChild(option);
                regions.forEach(function (region) {
                    var option = document.createElement('option');
                    option.value = region;
                    option.textContent = region;
                    senderStateSelect.appendChild(option);
                });
                senderStateSelect.disabled = false;
            });
            senderStreetAutocomplete.addListener('place_changed', function () {
                var place = senderStreetAutocomplete.getPlace();
                if (!place.geometry) {
                    return;
                }
                // 清空所有字段
                senderApartmentInput.value = '';
                senderCityInput.value = '';
                senderStateSelect.value = '';
                senderPostalCodeInput.value = '';
                senderCountrySelect.value = '';

                // 收集地址组件数据
                var addressData = {
                    street: '',
                    city: '',
                    state: '',
                    postalCode: '',
                    country: ''
                };

                for (var i = 0; i < place.address_components.length; i++) {
                    var component = place.address_components[i];
                    if (component.types.indexOf('street_number') !== -1) {
                        addressData.street = component.long_name;
                    } else if (component.types.indexOf('route') !== -1) {
                        addressData.street += ' ' + component.long_name;
                    } else if (component.types.indexOf('locality') !== -1) {
                        addressData.city = component.long_name;
                    } else if (component.types.indexOf('administrative_area_level_1') !== -1) {
                        addressData.state = component.long_name;
                    } else if (component.types.indexOf('postal_code') !== -1) {
                        addressData.postalCode = component.long_name;
                    } else if (component.types.indexOf('country') !== -1) {
                        addressData.country = component.long_name;
                    }
                }

                // 先设置国家,触发change事件加载对应州选项
                if (addressData.country) {
                    senderCountrySelect.value = addressData.country;
                    senderCountrySelect.dispatchEvent(new Event('change'));
                }

                // 再设置其他字段
                senderStreetInput.value = addressData.street.trim();
                senderCityInput.value = addressData.city;
                senderStateSelect.value = addressData.state;
                senderPostalCodeInput.value = addressData.postalCode;
            });

            senderCityAutocomplete.addListener('place_changed', function () {
                var place = senderCityAutocomplete.getPlace();
                if (!place.geometry) {
                    return;
                }
                // 清空所有字段
                senderStreetInput.value = '';
                senderApartmentInput.value = '';
                senderStateSelect.value = '';
                senderPostalCodeInput.value = '';
                senderCountrySelect.value = '';

                // 收集地址组件数据
                var addressData = {
                    city: '',
                    state: '',
                    country: ''
                };

                for (var i = 0; i < place.address_components.length; i++) {
                    var component = place.address_components[i];
                    if (component.types.indexOf('locality') !== -1) {
                        addressData.city = component.long_name;
                    } else if (component.types.indexOf('administrative_area_level_1') !== -1) {
                        addressData.state = component.long_name;
                    } else if (component.types.indexOf('country') !== -1) {
                        addressData.country = component.long_name;
                    }
                }

                // 先设置国家,触发change事件加载对应州选项
                if (addressData.country) {
                    senderCountrySelect.value = addressData.country;
                    senderCountrySelect.dispatchEvent(new Event('change'));
                }

                // 再设置其他字段
                senderCityInput.value = addressData.city;
                senderStateSelect.value = addressData.state;
            });
        }
        google.maps.event.addDomListener(window, 'load', initialize);
    </script>

</head>

<body>
    <div>
        <label for="sender_street">Street Address:</label>
        <input type="text" id="sender_street" name="sender_street">
    </div>
    <div>
        <label for="sender_apartment">Apartment, suite, etc.:</label>
        <input type="text" id="sender_apartment" name="sender_apartment">
    </div>
    <div>
        <label for="sender_city">City:</label>
        <input type="text" id="sender_city" name="sender_city" required>
    </div>
    <div>
        <label for="sender_state">State/Province:</label>
        <select id="sender_state" name="sender_state" disabled required>
        </select>
    </div>
    <div>
        <label for="sender_postal_code">Zip/Postal Code:</label>
        <input type="text" id="sender_postal_code" name="sender_postal_code" required>
        <small>Enter 3-10 alphanumeric characters (letters A-Z, numbers 0-9) only.</small>
    </div>
    <div>
        <label for="sender_country">Select Country:</label>
        <select id="sender_country" name="sender_country">
            <option value="">Select a country</option>
            <option value="United States">United States</option>
            <option value="Canada">Canada</option>
        </select>
    </div>
</body>

</html>

额外优化

原代码中分别定义provinces和states的逻辑被合并成了regions变量,减少了冗余代码,逻辑更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 20:47:38