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實現三級聯動