1. 程式人生 > >javascript利用selected屬性實現省市區三級聯動

javascript利用selected屬性實現省市區三級聯動

javascript實現省市區三級聯動

原理是根據<select>選框下<option>的selected屬性來確定上一個值被選中,確定陣列下標,傳遞給下一個陣列作為迴圈結束值。

這是頁面未進行任何操作時的原始介面。


這是點選省份下拉列表中的一個選項之後,城市與區縣,均會預設選中第一個。


下面看程式碼:

html只定義了三個select框

省份:<select id="province" onchange="cityShow()"></select>
城市:<select id="city" onchange="areaShow()"></select>
區/縣<select id="area"></select>
省份,城市,區縣分別是一維、二維、三維陣列
var provinceArr=["請選擇省份","四川","重慶","雲南"];
var cityArr=[["請選擇城市"],
             ["成都","達州","綿陽"],
             ["萬州","沙坪壩"],
             ["昆明","大理","麗江"]];
var areaArr=[[["請選擇區域"]],
             [["錦江區","青羊區","金牛區","高新區"],["達縣","渠縣"],["綿陽市1","綿陽市2"]],
             [["五橋","百安"],["西永","大學城"]],
             [["昆明市1","昆明市2"],["洱海","蒼山","下關"],["古城","玉龍縣"]]];
對資料進行初始化

用了三個for()巢狀迴圈。這裡程式碼我都是複製貼上,修改迴圈變數和節點物件。

邏輯很簡單,先無腦將省份數組裡的資料新增到pro下拉選框中,當選中某個省份時,能夠獲取到下標值,將這個下標值作為cityArr數組裡的第一個索引值,此時cityArr[i] 就相當於一個一維陣列了,再來迴圈裡面的資料。

同理,取到i ,j 之後,作為areaArr的前兩個索引值,再來找areaArr[i][j]裡的值,即區縣。

//定義全域性變數
var pro=document.getElementById("province");
var city=document.getElementById("city");
var area=document.getElementById("area");

// 初始化,將省份的陣列傳到頁面option裡面
for(var i=0;i<provinceArr.length;i++){
	//建立節點物件,建立節點的內容,將內容寫入到節點物件中去,並新增到上一個父節點
    	var proSel=document.createElement("option");
    	var proTxt=document.createTextNode(provinceArr[i]);
    	proSel.appendChild(proTxt);
    	pro.appendChild(proSel);
    	
    	//將城市的陣列傳到頁面option裡面
    	if(pro[i].selected){
    		for(var j=0;j<cityArr[i].length;j++){
    			//建立節點物件,建立節點的內容,將內容寫入到節點物件中去,並新增到上一個父節點
    			  var citySel=document.createElement("option");
    			  var cityTxt=document.createTextNode(cityArr[i][j]);
    			  citySel.appendChild(cityTxt);
    			  city.appendChild(citySel);
    			
    			//將區縣的陣列傳到頁面option裡面
    			  if(city[j].selected){
    				  for(var k=0;k<areaArr[i][j].length;k++){
    	                  var areaSel=document.createElement("option");
    	                  var areaTxt=document.createTextNode(areaArr[i][j][k]);
    	                  areaSel.appendChild(areaTxt);
    	                  area.appendChild(areaSel);
    			  }
    		}
    	}
    }
}
頁面初始化之後,就要根據事件往裡面新增資料了。

用select框的onchange事件來寫。

這裡有個 清空函式,最後來講。

這一塊是對province的onchange響應事件,因為我們已經選擇了一個省份了,所以只要讓後面的城市和區縣知道我選的省份的下標就好。

//建構函式,點選province下拉列表,響應onchange事件,對city進行操作
function cityShow(){
	//先清空上一次操作可能留下的資料
        delAll("city");	
        delAll("area");
	
	            for(var i=0;i<pro.length;i++){
	            	if(pro[i].selected){
	            		for(var j=0;j<provinceArr[i].length;j++){
	            			var citySel=document.createElement("option");
	                        var cityTxt=document.createTextNode(cityArr[i][j]);
	                        citySel.appendChild(cityTxt);
	                        city.appendChild(citySel);	           
	                //將區縣的陣列傳到頁面option裡面
	                  if(city[j].selected){
	                      for(var k=0;k<areaArr[i][j].length;k++){
	                          var areaSel=document.createElement("option");
	                          var areaTxt=document.createTextNode(areaArr[i][j][k]);
	                          areaSel.appendChild(areaTxt);
	                          area.appendChild(areaSel);
	                  }
	            }
	        }
	    }
	}
}

對city的onchange事件。我們只要判斷pro[i]和city[j]是否同時被選中,這樣就能將i,j的值傳給areaArr了,而不用往城市下拉框裡去新增資料。

//建構函式,點選city下拉列表,響應onchange事件,對area進行操作
function areaShow(){
	//先清空上一次操作可能留下的資料
	delAll("area");
	for(var i=0;i<pro.length;i++){
		//省份被選中的情況下,取proArr陣列的下標,作為cityArr陣列(二維陣列)的第一個索引值
		if(pro[i].selected){
			for(var j=0;j<cityArr[i].length;j++){
				//省份與城市被選中的情況下,取cityArr陣列(二維陣列)的兩個索引值,作為areaArr陣列(三維陣列)的第一個個索引值
				if(city[j].selected){
					for(var k=0;k<areaArr[i][j].length;k++){
						var areaSel=document.createElement("option");
                        var areaTxt=document.createTextNode(areaArr[i][j][k]);
                        areaSel.appendChild(areaTxt);
                        area.appendChild(areaSel);
					}
				}
			}
		}
	}
}

做到這裡其實三級聯動的功能已經能實現了,但是


咦?為什麼綿陽市1 2出現了兩次呢?

原因就是:

我每一次選擇的時候,上一次操作遺留下來的資料沒有被清空,當我再點選的時候,進行迴圈判定之後,會再次寫入到下拉框當中。

所以有必要在每次onchange操作的時候,將之前的資料全部清空,再往裡面寫入這次操作對應的資料。

封裝一個清空子節點的函式,只需在onchange事件函式頭部將city或者area傳入到這裡面去,就能執行清空操作,再次寫入,就完全不受影響啦~   

在我上面的程式碼裡面已經添加了這句話。

function delAll(theId){
    var theOb=document.getElementById(theId);
    var arr=theOb.childNodes;
    for(var j=arr.length;j>0;j--){  
    	theOb.removeChild(arr[j-1]);   
    }
}

再來看看效果,就是圖2的樣子了。

雖然這種方法程式碼行比較多,但是邏輯較簡單,程式碼還可以直接複製(我只寫了第一個迴圈和新增節點和內容),後面都是copy,綜上還是一個不錯的適合新手的方法。

下面貼上我用jquery寫的三級聯動,程式碼量更少,操作更簡單,實現的功能也更實際點選檢視jquery實現三級聯動