使用Select2与Ajax保留联动下拉菜单localStorage存储的选中值
问题根因
你的代码存在异步时序问题:加载州/省选项的AJAX是异步请求,你在触发国家下拉change事件后立即执行州下拉的赋值操作,此时AJAX请求还未返回,州下拉的option选项还没有被渲染到页面,无法匹配到localStorage中存储的州ID,因此选中逻辑失效。
同时你现有代码只实现了从localStorage读取值的逻辑,缺少下拉变更时把值写入localStorage的逻辑,也是值无法持久化的原因之一。
修复方案
- 补充下拉值变更时的localStorage存储逻辑,在国家、州、城市每次变更时都把最新值存入localStorage
- 把州、城市的选中赋值逻辑放到对应AJAX请求成功、选项渲染完成之后执行,保证赋值时对应option已经存在
- 补充优化:你设置了AJAX的
dataType: "json",jQuery会自动将返回结果解析为JSON对象,不需要额外调用JSON.parse(),否则会抛出类型错误
修改后的完整JS代码
$(document).ready(function() { // 初始化读取本地存储的值 var savedCountry = localStorage.getItem('selected_country') || ''; var savedState = localStorage.getItem('selected_state') || ''; var savedCity = localStorage.getItem('selected_city') || ''; $('#country').select2(); $('#state').select2(); $('#city').select2(); $('select[name="country"]').on('change', function() { var country_id = $(this).val(); // 存储选中的国家 localStorage.setItem('selected_country', country_id); // 国家变更后清空已存储的州和城市 localStorage.removeItem('selected_state'); localStorage.removeItem('selected_city'); if (country_id) { $.ajax({ url: "/world/getStates.php", type: "GET", data: { 'country_id': country_id }, dataType: "json", success: function(data) { $('select[name="state"]').empty(); $('select[name="city"]').empty(); $('select[name="state"]').append('<option value="">Select State</option>'); // 移除多余的JSON.parse,data已经是解析好的对象 $.each(data, function(key, value) { $('select[name="state"]').append('<option value="' + value.id + '">' + value.name + '</option>'); }); // 州选项渲染完成后,判断是否有存储的州值,有则设置选中 if (savedState) { $('#state').val(savedState).trigger('change'); // 赋值完成后清空临时存储的savedState,避免重复触发 savedState = ''; } } }); } else { $('select[name="state"]').empty(); $('select[name="city"]').empty(); } }); $('select[name="state"]').on('change', function() { var country_id = $('#country').val(); var state_id = $(this).val(); // 存储选中的州 localStorage.setItem('selected_state', state_id); // 州变更后清空已存储的城市 localStorage.removeItem('selected_city'); if (state_id) { $.ajax({ url: "/world/getCities.php", type: "GET", data: { 'country_id': country_id, 'state_id': state_id }, dataType: "json", success: function(data) { $('select[name="city"]').empty(); $('select[name="city"]').append('<option value="">Select City</option>'); // 移除多余的JSON.parse $.each(data, function(key, value) { $('select[name="city"]').append('<option value="' + value.id + '">' + value.name + '</option>'); }); // 城市选项渲染完成后,判断是否有存储的城市值,有则设置选中 if (savedCity) { $('#city').val(savedCity).trigger('change'); savedCity = ''; } } }); } else { $('select[name="city"]').empty(); } }); $('select[name="city"]').on('change', function() { // 存储选中的城市 localStorage.setItem('selected_city', $(this).val()); }); // 页面加载完成后初始化国家选中,州和城市的选中会在对应AJAX完成后自动执行 $('#country').val(savedCountry).trigger('change'); });
额外注意点
你现有HTML中国家下拉的option没有设置value属性,此时val()方法会返回option的文本内容,需要保证和后端接口返回的国家ID规则一致,否则会导致请求州列表失败。建议给国家option补充和后端匹配的value值,示例如下:
<select class="csc-select" name="country" id="country"> <option value="">Select Country</option> <option value="1">Australia</option> <option value="2">Denmark</option> <option value="3">Japan</option> <option value="4">Norway</option> <option value="5">Switzerland</option> </select>
内容的提问来源于stack exchange,提问作者Blu3
相关产品推荐
相关产品推荐

