您的位置:首页 > Web前端 > JavaScript

javascript省市地区联动【素材】

2010-09-12 11:54 232 查看
资源源码下载地址:http://download.csdn.net/source/2689287

最新版本请到https://github.com/oxcow/ProvCitySelected下载。

利用js读取xml文件,通过xpath表达式获取所要数据,封装实现联动菜单。

整个过程使用OOP思想进行处理。主要包含5个对象:

HtmlSelect对象。该对象为页面下拉标签对象;
ProvinceAndCityLink对象。该对象为联动菜单基类对象。
Province对象。该对象继承自ProvinceAndCityLink对象,为下拉菜单对象。
City对象。该对象继承自ProvinceAndCityLink对象,为下拉菜单对象。
Area对象。该对象继承自ProvinceAndCityLink对象,为地区下拉菜单对象。

类图如下:


主代码如下:
/**
* html select 标签类
*
* @param {string}
*            sId 标签id
* @param {string}
*            sName 标签 name
* @param {string}
*            sVal 标签值
* @constructor
* @returns {HtmlSelect}
*/
function HtmlSelect(sId, sName, sVal) {
this.id = sId;
this.name = sName;
this.val = sVal;
this.select = this.createSelect_();
}
/**
* 创建select元素
* @private
* @returns {Element} select element
*/
HtmlSelect.prototype.createSelect_ = function() {
var oSelect = document.createElement("select");
oSelect.setAttribute("id", this.id);
oSelect.setAttribute("name", this.name);
return  oSelect;
};
/**
* 创建并添加 option 元素
*
* @param {string}
*            sVal option 元素 value
* @param {string}
*            sText option 元素 显示值
* @returns {Element} option element
*/
HtmlSelect.prototype.addOption = function(sVal, sText) {
/**
* 创建option方法1<br/>
* 使用该方法IE6/FF下,默认selected不会出现错位
*/
var option = document.createElement("option");
option.appendChild(document.createTextNode(sText));
option.setAttribute('value', sVal);
if (this.val && sVal == this.val) {
option.setAttribute('selected', 'selected');
}
this.select.appendChild(option);
/**
* 创建option方法2<br/>
* 使用该方法IE6下,默认selected会出现错位
*/
//	var option = null;
//	if (this.val && sVal == this.val) {
//		option = new Option(sText, sVal, true, true);
//	} else {
//		option = new Option(sText, sVal, false, false);
//	}
//	try {
//		this.select.add(option, null); // standards compliant
//	} catch (ex) {
//		this.select.add(option); // IE only
//	}

/**
* 创建option方法2<br/>
* 使用该方法IE6下,默认selected会出现错位
*/
//	var option = document.createElement("option");
//	option.value = sVal;
//	option.text = sText;
//	if (this.val && sVal == this.val) {
//		option.setAttribute('selected', 'true');
//	}
//	//this.select.appendChild(option);IE6下此时不可用appendChild添加
//	try {
//		this.select.add(option, null); // standards compliant
//	} catch (ex) {
//		this.select.add(option); // IE only
//	}
};
/**
* 清除 select 元素下所有的 option 元素
*
*/
HtmlSelect.prototype.cleanOptions = function() {
if (this.select && this.select.options.length != 0) {
for ( var i = this.select.options.length - 1; i >= 0; i--) {
this.select.remove(this.select.options[i]);
}
}
};
/**
* 显示select标签在页面中
*
* @param {string}
*            offset select元素父节点id
*/
HtmlSelect.prototype.showHtml = function(offset) {
var op = document.getElementById(offset);
op.appendChild(this.select);
};
/**
* 省市地区联动菜单类
*
* @param {string}
*            sOffset 位置
* @param {string}
*            sName 菜单名
* @param {string}
*            sVal 菜单值
* @constructor
* @returns {ProvinceAndCityLink}
*/
function ProvinceAndCityLink(sOffset, sName, sVal) {
this.xml = loadxml();
this.offset = sOffset;
this.id = "id_" + (new Date()).getTime();
this.name = sName;
this.val = sVal;
/**
* @type {HtmlSelect}
*/
this.htmlSelect = new HtmlSelect(this.id, this.name, this.val);
}
/**
* 初始化数据并显示在页面指定元素中
*
* @param {string}
*            xPath xPath表达式
*/
ProvinceAndCityLink.prototype.init = function(xPath) {
var xmlData = this.xml.documentElement.selectNodes(xPath);
if (!this.val && xmlData[0]) {// 如果没有默认值,则将第一个元素设置为默认值
this.val = xmlData[0].getAttribute("name");
this.htmlSelect.val = this.val;
}
for ( var i = 0; i < xmlData.length; i++) {
this.htmlSelect.addOption(xmlData[i].getAttribute("name"),
xmlData[i].getAttribute("name"));
}
this.htmlSelect.showHtml(this.offset);
};
/**
* 联动菜单onchange事件
*
* @param {string}
*            xPath 新数据 xPath 表达式
* @returns
*/
ProvinceAndCityLink.prototype.change = function(xPath) {
var oLink = ProvinceAndCityLink["link_" + this.id];// 获取onchange方法的绑定对象
oLink.htmlSelect.cleanOptions();
var sXpath = oLink.xPath.replace("&var", this.value);// 替换xPath中的变量部分
var xmlData = oLink.xml.documentElement.selectNodes(sXpath);
for ( var i = 0; i < xmlData.length; i++) {
oLink.htmlSelect.addOption(xmlData[i].getAttribute("name"),
xmlData[i].getAttribute("name"));
}
var oLinkedLink = ProvinceAndCityLink["link_" + oLink.id];// 获取被绑定对象onchange绑定的对象
if (oLinkedLink) {
oLinkedLink.htmlSelect.cleanOptions();
var data = xmlData[0].childNodes;
for ( var j = 0; j < data.length; j++) {
if (data[j].nodeType == 1) {// ELEMENT_NODE
oLinkedLink.htmlSelect.addOption(data[j]
.getAttribute("name"), data[j].getAttribute("name"));
}
}
}
};
/**
* 省份下拉对象
*
* @param {string}
*            sOffset 显示位置
* @param {string}
*            sName 变量名
* @param {string}
*            sVal 变量值
* @constructor
* @extends {ProvinceAndCityLink}
* @returns {Province}
*/
function Province(sOffset, sName, sVal) {
ProvinceAndCityLink.call(this, sOffset, sName, sVal);
this.xPath = "//province";
this.init(this.xPath);
}
Province.prototype = new ProvinceAndCityLink();
/**
* 省市联动
*
* @param {City}
*            oCity 联动市对象
*/
Province.prototype.linkCity = function(oCity) {
oCity.xPath = "//province[@name='&var']/city";
ProvinceAndCityLink["link_" + this.id] = oCity;// 指定当前province绑定的city
this.htmlSelect.select.onchange = this.change;
if (this.val) {
var sXpath = oCity.xPath.replace("&var", this.val);
oCity.init(sXpath);
}
};
/**
* 市下拉对象
*
* @param {string}
*            sOffset 显示位置
* @param {string}
*            sName 变量名
* @param {string}
*            sVal 变量值
* @param {boolean|undefined|null}
*            isInit
*            <ul>
*            是否初始数据。默认为false。
*            <li>如果只是构造单独的市下拉菜单,则需要设置该变量为true</li>
*            <li>如果是构造联动菜单,则需要将该变量设置为false</li>
*            </ul>
* @constructor
* @extends {ProvinceAndCityLink}
* @returns {City}
*/
function City(sOffset, sName, sVal, isInit) {
ProvinceAndCityLink.call(this, sOffset, sName, sVal);
this.xPath = "//city";
if (isInit) {
this.init(this.xPath);
}
}
City.prototype = new ProvinceAndCityLink();
/**
* 市区联动
*
* @param {Area}
*            oArea 区对象
*/
City.prototype.linkArea = function(oArea) {
oArea.xPath = "//city[@name='&var']/country";
ProvinceAndCityLink["link_" + this.id] = oArea;// // 指定当前city绑定的area
this.htmlSelect.select.onchange = this.change;
if (this.val) {
oArea.htmlSelect.cleanOptions();
var sXpath = oArea.xPath.replace("&var", this.val);
oArea.init(sXpath);
}
};
/**
* 地区下拉对象
*
* @param {string}
*            sOffset 显示位置
* @param {string}
*            sName 变量名
* @param {string}
*            sVal 变量值
* @param {boolean|undefined|null}
*            isInit
*            <ul>
*            是否初始数据。默认为false。
*            <li>如果只是构造单独地区下拉菜单,则需要设置该变量为true</li>
*            <li>如果是构造联动菜单,则需要将该变量设置为false</li>
*            </ul>
* @constructor
* @extends {ProvinceAndCityLink}
* @returns {Area}
*/
function Area(sOffset, sName, sVal, isInit) {
ProvinceAndCityLink.call(this, sOffset, sName, sVal);
this.xPath = "//country";
if (isInit) {
this.init(this.xPath);
}
}
Area.prototype = new ProvinceAndCityLink();


页面调用html代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>省市区联动菜单</title>
<mce:script type="text/javascript" src="loadxml.js" mce_src="loadxml.js"></mce:script>
<mce:script type="text/javascript" src="C_area.js" mce_src="C_area.js"></mce:script>
<mce:script type="text/javascript"><!--
window.onload = function() {
//单独取省(无默认值)
var singleProN = new Province('single_pro_n', 'sp1');
//单独取省(有默认值)
var singleProY = new Province('single_pro_y', 'sp2', '吉林省');
//单独取市(无默认值)
var singleCityN = new City('single_cit_n', 'sc1', '', true);
//单独取市(有默认值)
var singleCityY = new City('single_cit_y', 'sc2', '天津辖区', true);
// 信息量大,因此在加载的时候比较慢,不过FF相对于IE比较快
//单独取地区(无默认值)
var singleAreaN = new Area('single_area_n', 'sa1', '', true);
//单独取地区(有默认值)
var singleAreaY = new Area('single_area_y', 'sa2', '海淀区', true);
//省市联动(无默认值)
var pcProN = new Province('pc_p_n', 'pcp1');
var pcCityN = new City('pc_c_n', 'pcc1');
pcProN.linkCity(pcCityN);
//省市联动(有默认值)
var pcProY = new Province('pc_p_y', 'pcp2', "江苏省");
var pcCityY = new City('pc_c_y', 'pcc2', "常州市");
pcProY.linkCity(pcCityY);
//市地区联动(无默认值)
var caCityN = new City('ca_c_n', 'cac1', '', true);
var caAreaN = new Area('ca_a_n', 'caa1');
caCityN.linkArea(caAreaN);
//市地区联动(有默认值)
var caCityY = new City('ca_c_y', 'cac2', "唐山市", true);
var caAreaY = new Area('ca_a_y', 'caa2', '丰南区');
caCityY.linkArea(caAreaY);
//省市地区联动(无默认值)
var lp = new Province('lp', 'lp');
var lc = new City('lc', 'lc');
var la = new Area('la', 'la', '', false);
lp.linkCity(lc);
lc.linkArea(la);
//省市地区联动(有默认值)
var lp1 = new Province('lp1', 'lp1', '湖南省');
var lc1 = new City('lc1', 'lc1', '湘潭市');
var la1 = new Area('la1', 'la1', '', false);
lp1.linkCity(lc1);
lc1.linkArea(la1);
}
// --></mce:script>
</head>
<body>
<fieldset><legend>单独取省</legend> 无默认值: <span id="single_pro_n"></span>
有默认值: <span id="single_pro_y"></span></fieldset>
<br />
<fieldset><legend>单独取市</legend> 无默认值: <span id="single_cit_n"></span>
有默认值: <span id="single_cit_y"></span></fieldset>
<br />
<fieldset><legend>单独取地区</legend> 无默认值: <span
id="single_area_n"></span> 有默认值: <span id="single_area_y"></span></fieldset>
<br />
<fieldset><legend>省市联动</legend> 无默认值: <span id="pc_p_n"></span><span
id="pc_c_n"></span> 有默认值: <span id="pc_p_y"></span><span id="pc_c_y"></span>
</fieldset>
<br />
<fieldset><legend>市地区联动</legend> 无默认值: <span id="ca_c_n"></span><span
id="ca_a_n"></span> 有默认值: <span id="ca_c_y"></span><span id="ca_a_y"></span>
</fieldset>
<br />
<fieldset><legend>市地区联动</legend> 无默认值: <span id="lp"></span><span
id="lc"></span> <span id="la"></span> 有默认值: <span id="lp1"></span><span
id="lc1"></span><span id="la1"></span></fieldset>
</body>
</html>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: