jQuery实现国家-城市级联下拉框JSON填充时map方法报错排查
报错根因与联动下拉实现修正
触发country.map is not a function的核心原因
- 对接口返回的数据结构认知偏差:该JSON数据顶层为键值对结构,键是国家名称,对应的值直接是该国所有城市组成的数组,不存在嵌套的“国家对象包含城市数组”的两层结构。
代码中多嵌套了一层无意义的$.map遍历:selectData[this.value]本身就已经是当前选中国家的城市数组,再对这个数组做$.map遍历时,回调拿到的每个元素是单个城市字符串(也就是原代码里命名为country的变量),字符串类型没有原生的map方法,直接触发类型错误。 - 数组遍历的参数顺序颠倒:即便去掉多余的嵌套遍历,原代码的数组
map回调参数顺序也是错误的。原生数组map的回调第一个参数是当前遍历的元素值,第二个才是元素索引,原代码中function(key, val)将值和索引位置写反,最终生成的下拉项会出现文本是索引、值是城市名的逻辑错误。 - 取值稳定性问题:初始化国家下拉框时,只给option设置了文本内容,没有同步设置value属性,部分特殊场景下会出现下拉框取值异常。
修正后可直接运行的完整代码
$(document).ready(function() { let $country; $.getJSON("https://raw.githubusercontent.com/russ666/all-countries-and-cities-json/master/countries.json", function(selectData) { function updateSelects() { const selectedCountryName = this.value; // 取对应国家的城市数组,空值兜底避免异常 const cityList = selectData[selectedCountryName] || []; // 遍历城市数组生成option,参数顺序匹配原生map规则 const cityOptions = cityList.map(function(cityName, index) { return $("<option />").text(cityName).val(index); }); $("#city").empty().append(cityOptions); } // 绑定国家下拉框的联动事件 $country = $("#country").on("change", updateSelects); // 初始化国家下拉选项,显式设置value属性 for (const countryName in selectData) { // 过滤原型链上的属性,避免异常选项 if (Object.hasOwn(selectData, countryName)) { $("<option />").text(countryName).val(countryName).appendTo($country); } } // 首次触发联动加载默认选中国家的城市列表 $country.change(); }); });
<html> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> </head> <body> <div style="margin: 50px auto; text-align: center;"> <select id="country" style="font-size: 20px; width: 100px;"></select> <select id="city" style="font-size: 20px; width: 100px;"></select> </div> </body> </html>
内容的提问来源于stack exchange,提问作者NewJavaEnthusiast
相关产品推荐
相关产品推荐

