我想簡化我的js,感覺重複的code很多,但我不知道該從哪裡下手。新手麻煩高手指點
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
</style>
</head>
<body>
<form action="">
<select id="country">
<option>選擇國家</option>
<option value="taiwan">台灣</option>
<option value="usa">美國</option>
</select>
<select id="city">
</select>
<select id="district">
</select>
</form>
<script>
var taiwan = [
{
"CityName": "臺北市",
"CityEngName": "Taipei City",
"AreaList": [
{
"ZipCode": "100",
"AreaName": "中正區",
"AreaEngName": "Zhongzheng Dist."
},
{
"ZipCode": "103",
"AreaName": "大同區",
"AreaEngName": "Datong Dist."
}
]
},
{
"CityName" : "新竹市",
"CityEngName" : "Hsinchu city",
"AreaList" : [
{
"ZipCode":300,
"AreaName":"東區",
"AreaEngName":"East Dist"
},
{
"ZipCode":300,
"AreaName":"北區",
"AreaEngName":"North Dist"
}
]
}
];
console.log(taiwan[0]['AreaList'].length);
var usa =[];
window.onload = function(){
document.getElementById('country').addEventListener('change',function(){
switch(this.value){
case '':
break;
case "taiwan":
var list = taiwan;
break;
case "usa":
var list = usa;
break;
};
document.getElementById('city').innerHTML = ''; //清空選單
document.getElementById('district').innerHTML = ''; //清空選單
var option = document.createElement('option');
option.innerHTML = '<option>'+'選擇城市'+'</option>';
document.getElementById('city').insertBefore(option, null);
for(i=0; i<list.length ;i++){
var option = document.createElement('option');
option.innerHTML = list[i]['CityName'];
option.setAttribute('value', list[i]["CityEngName"]);
document.getElementById('city').insertBefore(option, null);
}
});
document.getElementById('city').addEventListener('change',function(){
switch(this.value){
case '':
break;
case "Taipei City":
var list = taiwan[0]['AreaList'];
break;
case "Hsinchu city":
var list = taiwan[1]['AreaList'];
break;
};
document.getElementById('district').innerHTML = ''; //清空選單
var option = document.createElement('option');
option.innerHTML = '<option>'+'選擇區域'+'</option>';
document.getElementById('district').insertBefore(option, null);
for(i=0; i < list.length; i++){
var option = document.createElement('option');
option.innerHTML = list[i]['AreaName'];
document.getElementById('district').insertBefore(option, null);
}
});
};
</script>
</body>
</html>
說真的,能用javascript原生碼寫成這樣算不錯了。
真要簡化的話。給你幾個建議好了。
1.insertBefore的動作可以在for完後再做。你也可以直接用innerHTML處理就好。
2.省略掉 switch 的判斷。全使用指標式資料。不要單純用0 1key值處理。全用指定key。你就可預不需要用switch處理。且你用switch處理也太累了吧。
最後,其實我建議你學一下jquery的處理方式,可以讓你的程式碼更乾淨易懂。
一些需要兩三行才能處理的,透過jquery一行就可以處理了。
const countrySelect = document.getElementById('country');
const citySelect = document.getElementById('city');
const districtSelect = document.getElementById('district');
let allCities = '';
let allAreas = '';
let defaultOption = '<option value = "">---請選擇---</option>';
countrySelect.innerHTML = `${defaultOption}${allCountries.map(el => `<option value = "${el.CountryEngName}">${el.CountryName}</option>`).join('')}`;
countrySelect.addEventListener('change', (e) => {
const countryPosition = allCountries.map(country => country.CountryEngName).indexOf(e.target.value);
allCities = countryPosition > -1
? allCountries[countryPosition].Cities
: [];
citySelect.innerHTML = `${defaultOption}${allCities.map(city => `<option value = "${city.CityEngName}">${city.CityName}</option>`).join('')}`;
districtSelect.innerHTML = defaultOption;
});
citySelect.addEventListener('change', (e) => {
const cityPosition = allCities.map(city => city.CityEngName).indexOf(e.target.value);
allAreas = cityPosition > -1
? allCities[cityPosition].AreaList
: [];
districtSelect.innerHTML = `${defaultOption}${allAreas.map(area => `<option value = "${area.AreaEngName}">${area.AreaName}</option>`).join('')}`;
});
大概就這樣
主要就是
map
跟
Template literals
的應用
換了一下寫法
這個寫法就可以往 allData 加新的資料
且不用動 code
const options = {
taiwan: [ /* ... */ ],
usa: [ /* ... */ ]
}
const selectedValue = "taiwan";
const list = options[selectedValue]
另外 option 的 element 可以先寫入 fragment 已提高效能
我試著把它做成一個物件,可以透過 add 方法設定每層關聯的 key
最後再用 update 方法渲染選單
希望的使用方式如下:
new SelectChain(data)
.add('country','CountryEngName','CountryName','CityList','請選擇國家')
.add('city','CityEngName','CityName','AreaList','請選擇城市')
.add('area','AreaEngName','AreaName',null,'請選擇區域')
.update();
實作後的參考範例:codepen