DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> jQuery入門知識 >> JQuery特效代碼 >> 使用jQuery+HttpHandler+xml模擬一個三級聯動的例子
使用jQuery+HttpHandler+xml模擬一個三級聯動的例子
編輯:JQuery特效代碼     
如下是實現過程:
第一步:准備xml文件,並放置在網站根目錄下,名為Area.xml
代碼如下:
<?xml version="1.0" encoding="utf-8" ?>
<area>
<province id="1" name="北京">
<city id="1" name="北京">
<county id="1" name="東城區" />
<county id="2" name="西城區" />
</city>
</province>
<province id="2" name="河北省">
<city id="1" name="石家莊市">
<county id="1" name="正定縣" />
<county id="2" name="靈壽縣" />
</city>
<city id="2" name="邯鄲市">
<county id="1" name="邯鄲縣" />
<county id="2" name="永年縣" />
</city>
</province>
<province id="3" name="海南省">
<city id="1" name="海口市">
<county id="1" name="龍華區" />
<county id="2" name="秀英區" />
<county id="3" name="美蘭區" />
</city>
<city id="2" name="三亞市">
<county id="1" name="天涯鎮" />
<county id="2" name="鳳凰鎮" />
</city>
</province>
</area>

第二步:創建與xml文件中定義的元素對應的實體類。
<province/>對應province類
代碼如下:
public class Province
{
private string id;
/// <summary>
/// 編號
/// </summary>
public string Id
{
get { return id; }
set { id = value; }
}
private string name;
/// <summary>
/// 名稱
/// </summary>
public string Name
{
get { return name; }
set { name = value; }
}
}

<city/>對應City類:
代碼如下:
public class City
{
private string id;
/// <summary>
/// 編號
/// </summary>
public string Id
{
get { return id; }
set { id = value; }
}
private string name;
/// <summary>
/// 名稱
/// </summary>
public string Name
{
get { return name; }
set { name = value; }
}
}

<county/>對應county類:
代碼如下:
public class County
{
private string id;
/// <summary>
/// 編號
/// </summary>
public string Id
{
get { return id; }
set { id = value; }
}
private string name;
/// <summary>
/// 名稱
/// </summary>
public string Name
{
get { return name; }
set { name = value; }
}
}

第三步:編寫服務器端處理程序類:Handler.cs
代碼如下:
/// <summary>
2 /// 處理程序
3 /// </summary>
4 public class Handler : IHttpHandler
5 {
6
7 private static XDocument doc;
8 private string filePath = HttpContext.Current.Server.MapPath("~/Area.xml");
9 //javascript序列化類
private static JavaScriptSerializer jss = new JavaScriptSerializer();
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
string result = "failure";//默認返回結果為失敗
HttpRequest req = context.Request;
string province = req["province"];//獲取用戶選擇的省的編號
string city = req["city"];//獲取用戶選擇的市的編號
string county = req["county"];//獲取用戶選擇的縣的編號
string type = req["type"];//獲取用戶需要獲取的省市縣列表的類型
InitDoc();
if (type.HasValue())
{
switch (type.ToLower())
{
case "province"://如果用戶需要獲取省級列表
result = jss.Serialize(GetProvinceList());
break;
case "city"://如果用戶需要獲取的是市級列表
result = jss.Serialize(GetCityListByProvince(province));
break;
case "county"://如果用戶需要獲取的是縣級列表
result = jss.Serialize(GetCountyListByCity(province, city));
break;
default:
break;
}
}
//將結果以文本的格式返回給客戶端
context.Response.Write(result);
}
/// <summary>
/// 初始化文檔對象
/// </summary>
private void InitDoc()
{
if (doc == null)
{
doc = XDocument.Load(filePath);
}
}
/// <summary>
/// 初始化省級列表
/// </summary>
private List<Province> GetProvinceList()
{
List<Province> list = new List<Province>();
if (doc != null)
{
XElement root = doc.Root;
foreach (var prov in root.XPathSelectElements("province"))
{
list.Add(new Province()
{
Id = prov.Attribute("id").Value,
Name = prov.Attribute("name").Value
});
}
}
return list;
}
/// <summary>
/// 根據省級編號獲取市級編號
/// </summary>
/// <param name="provId">省級編號</param>
private List<City> GetCityListByProvince(string provId)
{
List<City> list = new List<City>();
if (doc != null)
{
XElement root = doc.Root;
//xpath表達式:/area/province[@id='1']/city
string queryPath = "/area/province[@id='" + provId + "']/city";
foreach (var city in root.XPathSelectElements(queryPath))
{
list.Add(new City()
{
Id = city.Attribute("id").Value,
Name = city.Attribute("name").Value
});
}
}
return list;
}
/// <summary>
/// 根據省級編號和市級編號獲取縣級編號
/// </summary>
/// <param name="provId">省級編號</param>
/// <param name="cityId">市級編號</param>
private List<County> GetCountyListByCity(string provId, string cityId)
{
List<County> list = new List<County>();
if (doc != null)
{
XElement root = doc.Root;
string queryPath = "/area/province[@id='" + provId + "']/city[@id='" + cityId + "']/county";
foreach (var county in root.XPathSelectElements(queryPath))
{
list.Add(new County()
{
Id = county.Attribute("id").Value,
Name = county.Attribute("name").Value
});
}
}
return list;
}
public bool IsReusable
{
get
{
return false;
}
}
}

在這裡,查詢xml我采用的是System.Xml.XPath命名空間下的XPathSelectElements(string xpath)方法和XPathSelectElement(string xpath)方法,在根據省級編號獲取市級編號的方法裡面,我使用了xpath表達式(假設傳入的省級編號為1):/area/province[@id='1']/city,這個表達式以“/”開頭,表示使用絕對路徑,因為area為根節點所以從area開始,接著它下面有province元素,當我想獲取area下所有province元素中id屬性值為1的province元素時,我可以使用/area/province[@id='1'],即在province後面加上[@id='1']這個條件,這時我就獲取到了area下id屬性為1的province元素了。接著我要獲取該province元素下所有的city,那麼只需在後面加上/city即可,所以最終的xpath表達式為:/area/province[@id='1']/city。
還有,因為此查詢的xml是在當前網站的根目錄,如果是在其它地方,那麼在查詢的時候要加上namespace
將從xml文件中讀取到的值組裝成對應的實體對象只後,我使用了System.Web.Script.Serialization命名空間下的JavaScriptSerializer類中的Serialize方法將得到的實體對象序列化成json數據返回給客戶端。
第四步:編寫html和js。
代碼如下:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>省市縣三級聯動下拉列表</title>
<script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$.post("/Handler.ashx", { "type": "province" }, function (data, status) {
if (status == "success") {
if (data != "failure") {
data = $.parseJSON(data); //解析服務器返回的json數據
for (var i = 0; i < data.length; i++) {
var value = data[i].Id + ":" + data[i].Name; //設置option選項的值,格式為:"編號:名稱"
$("#province").append("<option value='" + value + "'>" + data[i].Name + "</option>");
}
}
}
}, "text");
$("#province").change(function () {
var selectValue = $(this).val(); //獲取選擇的省級option的值
var provId = selectValue.split(':')[0]; //取出編號
var provTxt = selectValue.split(':')[1]; //取出名稱
$("#txtProvince").html(provTxt); //顯示選擇的省的名稱
$("#city").html("<option>==請選擇市==</option>"); //當省級改變時將市級清空
$("#county").html("<option>==請選擇縣==</option>"); //當省級改變時將縣級清空
$.post("/Handler.ashx", { "province": provId, "type": "city" }, function (data, status) {
if (status == "success") {
if (data != "failure") {
data = $.parseJSON(data);
for (var i = 0; i < data.length; i++) {
var value = data[i].Id + ":" + data[i].Name;
$("#city").append("<option value='" + value + "'>" + data[i].Name + "</option>");
}
}
}
}, "text");
});
$("#city").change(function () {
var provId = $("#province").val().split(':')[0];
var selectValue = $(this).val(); //同上
var cityId = selectValue.split(':')[0]; //同上
var cityTxt = selectValue.split(':')[1]; //同上
$("#txtCity").html(cityTxt); //顯示選擇的市的名稱
$("#county").html("<option>==請選擇縣==</option>"); //同上
$.post("/Handler.ashx", { "province": provId, "city": cityId, "type": "county" }, function (data, status) {
if (status == "success") {
if (data != "failure") {
data = $.parseJSON(data);
for (var i = 0; i < data.length; i++) {
var value = data[i].Id + ":" + data[i].Name;
$("#county").append("<option value='" + value + "'>" + data[i].Name + "</option>");
}
}
}
}, "text");
});
$("#county").change(function () {
$("#txtCounty").html($(this).val().split(':')[1]); //顯示選擇的縣的名稱
});
});
</script>
</head>
<body>
<!--省-->
<select id="province" name="province">
</select>
<!--市-->
<select id="city" name="city">
</select>
<!--縣-->
<select id="county" name="county">
</select>
<br />
<span id="txtProvince" style="color: #ff0000;"></span>- <span id="txtCity" style="color: #ff0000;"></span>- <span id="txtCounty" style="color: #ff0000;"></span>
</body>
</html>

關於使用jQuery與服務器通信,我使用的是$.post方法,該方法的具體使用可以參考jQuery官方文檔,這裡我想說的是,遍歷後通過對象.屬性訪問時,這個屬性的名字是區分大小寫的,這個名字是服務器端定義的名字,因為服務器序列化的是服務器端的實體對象。
在這個例子中,關鍵點就是如何使用XPath表達式,如何調用System.Xml.XPath命名空間下的XPathSelectElements(string xpath)方法。
最終結果如下圖:

代碼13,31,50行可以優化。
不建議多次修改DOM結構,可以拼接字符串後一次append
數據源是xml,我會用xslt來解析xml直接輸出<option>,這樣就不用再前台拼接字符串了。要求所有節點ID不能有相同。
代碼如下:
<select id="province" name="province" next="#city">
</select>
<select id="city" name="city" next="#county">
<option>==請選擇市==</option>
</select>
</form>
<select id="county" name="county">
<option>==請選擇縣==</option>
</select>

<script type="text/javascript">
$("#province,#city").change(function () {
var nextSelect = $(this.getAttribute("next"));

//if (nextSelect.size() > 0) {
nextSelect.find("option:gt(0)").remove();

var _id = $(this).find("option:selected").val();
var query = { parentId: _id };
$.get("/Handler.ashx", query, function (data, status) {
//...
nextSelect.append("<option>...</option>....");
});
//}
});
</script>
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved