省市区三级联动(数组、JSON实现)

省市区联动下拉效果在WEB中应用非常广泛,尤其在一些会员信息系统、电商网站最为常见。
下面举例一种实现方式:
htlm代码:

<form>
	<select id="proSelect">
		<option>选择省</option>
	</select>
	<select id="citySelect">
		<option>选择市</option>
	</select>
	<select id="areaSelect">
		<option>选择区</option>
	</select>
</form>

js代码:

var pro=document.getElementById("proSelect");
var city=document.getElementById("citySelect");
var area=document.getElementById("areaSelect");
pro.addEventListener("change",addCity);
//将指定的监听器添加到该对象上 当pro触发change事件时 addCity()就会被执行。
city.addEventListener("change",addArea);
pro.add(new Option("陕西省","陕西省"));
//创建一个option对象 new Option(text, value) 并添加到<seletc>中
pro.add(new Option("山东省","山东省"));
function addCity(){
	var choiceVal=pro.value;
	city.options.length=1;
	//options是个数组 里面存放着多个<option>标签 此处长度为1是为了保留默认的<option>
	area.options.length=1;
	if(choiceVal=="陕西省"){
		city.add(new Option("西安市","西安市"));
		city.add(new Option("渭南市","渭南市"));
	}
	else if (choiceVal=="山东省"){
		city.add(new Option("济南市","济南市"));
		city.add(new Option("济宁市","济宁市"));
	}
}
function addArea(){
	var choiceVal=city.value;
	if(choiceVal=="西安市"){
		area.add(new Option("未央区","未央区"));
		area.add(new Option("碑林区","碑林区"));
	}
	else if (choiceVal=="渭南市"){
		area.add(new Option("临渭区","临渭区"));
		area.add(new Option("华州区","华州区"));
	}
	else if (choiceVal=="济南市"){
		area.add(new Option("市中区","市中区"));
		area.add(new Option("历城区","历城区"));
	}
	else if (choiceVal=="济宁市"){
		area.add(new Option("任城区","任城区"));
		area.add(new Option("兖州区","兖州区"));
	}
}

这样虽然实现了省级联动的效果,但是如果省市较多,添加进去十分麻烦,也很不清晰。因此我们不建议使用这样的方法实现。
一般的我们经常看到的关于级联样式的数据处理,例如省级联动,三级菜单等,一般这些数据是在数据库中存储的每一条数据的格式是:
ID-Name-Pid
现在我们不需要数据库,但是我们的数据不管是在数组还是在JSON的对象,我们的数据存储也要是这中形式。
数组格式举例:

var arrs=new Array();
//           id    name  pid
arrs[0]=['1','陕西','0'];
arrs[1]=['2','山东','0'];
arrs[2]=['3','西安','1'];
arrs[3]=['4','渭南','1'];
arrs[4]=['5','青岛','2'];
arrs[5]=['6','潍坊','2'];
arrs[6]=['7','富平','4'];

这样的数据格式特点是:省份的父ID(pid)都是0,因为它是最高一级;城市的父ID对应的是它的上一级省份的ID;地区的父id对应的是它的上一级城市的ID;这样就形成一个清晰的关系链。
举例:[‘1’,‘陕西’,‘0’];
[‘4’,‘渭南’,‘1’];
[‘7’,‘富平’,‘4’];
然后我们想:我们需要所有的省份的时候,我们只要遍历这个数组,把所有父ID为0的数据显示即可,接着我们每选择一个省份或者一个城市的时候,我们只要创建一个函数即可;这个函数传入的参数是当前省份或者城市的ID,找出所有对应的父ID等于当前这个参数id的所有数据,显示即可。
第二种方式 数组实现
js代码:

var arrs=new Array();
      //  id  name    pid
arrs[0]=['1','陕西省','0'];
arrs[1]=['2','山东省','0'];
arrs[2]=['3','西安市','1'];
arrs[3]=['4','渭南市','1'];
arrs[4]=['5','济南市','2'];
arrs[5]=['6','济宁市','2'];
arrs[6]=['7','未央区','3'];
arrs[7]=['8','碑林区','3'];
arrs[8]=['9','临渭区','4'];
arrs[9]=['10','华州区','4'];
arrs[10]=['11','市中区','5'];
arrs[11]=['12','历城区','5'];
arrs[12]=['13','任城区','6'];
arrs[13]=['14','兖州区','6'];
//添加省份
for(i in arrs){
	if(arrs[i][2]=='0'){
		pro.add(new Option(arrs[i][1],arrs[i][0]));
	}
}
function addCity(event){
	var value=event.target.value;
	/*event 对象代表事件的状态 比如事件在其中发生的元素 键盘按键的状态 鼠标的位置 鼠标按钮的状态。target 事件属性可返回触发该事件的节点 如生成事件的元素、文档或窗口。*/
	city.options.length=1;
	area.options.length=1;
//添加城市
	for(i in arrs){
		if(arrs[i][2]==value){
			city.add(new Option(arrs[i][1],arrs[i][0]));
		}
	}
}
function addArea(event){
	var value=event.target.value;
	area.options.length=1;
//添加区、县
	for(i in arrs){
		if(arrs[i][2]==value){
			area.add(new Option(arrs[i][1],arrs[i][0]));
		}
	}
}

看,这种方式是不是比第一种更清晰呢?在实现我们想要的效果的同时,代码可读性也较好。
上面提到,还可以用JSON来实现。那么,我们来了解一下JSON。
在 JS 语言中,一切都是对象。因此,任何支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。但是对象和数组是比较特殊且常用的两种类型。
JSON 键/值对:
JSON 键值对是用来保存 JS 对象的一种方式,和 JS 对象的写法也大同小异,键/值对组合中的键名写在前面并用双引号 “” 包裹,使用冒号 : 分隔,然后紧接着值:
{"firstName": "John"}
这很容易理解,等价于这条 JavaScript 语句:
{firstName = "John"}
这个示例非常简单,但是,当将多个键/值对串在一起时,JSON 就会体现出它的价值了。首先,可以创建包含多个键/值对的 记录,比如:

{ "firstName": "Brett", "lastName":"McLaughlin", "email": "aaaa" }

JSON 与 JS 对象的关系:
JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。
如:

var obj = {a: 'Hello', b: 'World'}; 
//这是一个对象,注意键名也是可以使用引号包裹的
var json = '{"a": "Hello", "b": "World"}';
 //这是一个 JSON 字符串,本质是一个字符串

要实现从对象转换为 JSON 字符串,使用 JSON.stringify() 方法,要实现从 JSON 转换为对象,使用 JSON.parse() 方法。
了解了JSON后,我们来看用JSON实现省级联动的方法。
js代码:

var con='['+
'{"id":"1","name":"陕西省","pid":"0"},'
+'{"id":"2","name":"山东省","pid":"0"},'
+'{"id":"3","name":"西安市","pid":"1"},'
+'{"id":"4","name":"渭南市","pid":"1"},'
+'{"id":"5","name":"济南市","pid":"2"},'
+'{"id":"6","name":"济宁市","pid":"2"},'
+'{"id":"7","name":"未央区","pid":"3"},'
+'{"id":"8","name":"碑林区","pid":"3"},'
+'{"id":"9","name":"临渭区","pid":"4"},'
+'{"id":"10","name":"华州区","pid":"4"},'
+'{"id":"11","name":"市中区","pid":"5"},'
+'{"id":"12","name":"历城区","pid":"5"},'
+'{"id":"13","name":"任城区","pid":"6"},'
+'{"id":"14","name":"兖州区","pid":"6"}'
+']';
var obj=JSON.parse(con);	
//从 JSON 转换为对象
for(i in obj){
	if(obj[i].pid=='0'){
		pro.add(new Option(obj[i].name,obj[i].id));
	}
}
function addCity(event){
	var value=event.target.value;
	city.options.length=1;
	area.options.length=1;
	for(i in obj){
		if(obj[i].pid==value){
			city.add(new Option(obj[i].name,obj[i].id));
		}
	}
}
function addArea(event){
	var value=event.target.value;
	area.options.length=1;
	for(i in obj){
		if(obj[i].pid==value){
			area.add(new Option(obj[i].name,obj[i].id));
		}
	}
}
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页