龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > web编程 > Javascript编程 >

自定义select皮肤的三级联动下拉菜单

时间:2012-12-29 08:41来源:未知 作者:admin 点击:
分享到:
这里提供一款自定义select皮肤的三级联动下拉菜单效果,把select下拉框定义的非常漂亮,有需要的朋友可以参考一下。 代码如下 !DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.
这里提供一款自定义select皮肤的三级联动下拉菜单效果,把select下拉框定义的非常漂亮,有需要的朋友可以参考一下。
 代码如下
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>自定义select皮肤的省市县三级联动下拉菜单</title>
<meta http-equiv="content-type" content="text/html;charset=gb2312">
<!--把下面代码加到<head>与</head>之间-->
<style type="text/css">
body,dl,dt,dd{margin:0;}
.AreaSetBox{float:left;padding:30px;}
.AreaSetBox dl{float:left;margin-right:10px;display:inline;position:relative;font-size:14px;}
.AreaSetBox dt{padding:0;float:left;border:1px solid #ccc;margin:0;background:#f3f3f3;height:20px;line-height:20px;cursor:default;}
.AreaSetBox dt span{padding:0 5px;float:left;}
.AreaSetBox dt span.arr{width:10px;height:20px;background:url("http://www.111cn.net/blog/upload/image/20111107065544.png") no-repeat -74px -81px;border-left:1px solid #ccc;}
.AreaSetBox dd{position:absolute;display:none;left:0;top:22px;background:white;border:1px solid #ccc;width:200px;padding:5px;}
.AreaSetBox dd span{float:left;width:99px;cursor:pointer;text-align:center;}
.AreaSetBox dd span:hover{background:#f1f1f1;}
</style>
</head>
<body>
<!--把下面代码加到<body>与</body>之间-->
<div id="citySelectTag" class="AreaSetBox">
 <dl>
  <dt>
   <span>选择省</span><span class="arr"></span>
   <input name="Area_province" type="hidden" value="">
  </dt>
  <dd></dd>
 </dl>
 <dl>
  <dt>
   <span>选择市</span><span class="arr"></span>
   <input name="Area_city" type="hidden" value="">
  </dt>
  <dd>
   您还没选择省
  </dd>
 </dl>
 <dl>
  <dt>
   <span>选择区县</span><span class="arr"></span>
   <input name="Area_District" type="hidden" value="">
  </dt>
  <dd>
   您还没选择市
  </dd>
 </dl>
</div>
<div id="citySelectTag2" class="AreaSetBox">
 <dl>
  <dt>
   <span>选择省</span><span class="arr"></span>
   <input name="Area_province" type="hidden" value="">
  </dt>
  <dd></dd>
 </dl>
 <dl>
  <dt>
   <span>选择市</span><span class="arr"></span>
   <input name="Area_city" type="hidden" value="">
  </dt>
  <dd>
   您还没选择省
  </dd>
 </dl>
 <dl>
  <dt>
   <span>选择区县</span><span class="arr"></span>
   <input name="Area_District" type="hidden" value="">
  </dt>
  <dd>
   您还没选择市
  </dd>
 </dl>
</div>
<script type="text/javascript" src="class_area.js" charset="gb2312"></script>
<script type="text/javascript" defer>
/**
* 闭包事件,判断并调用父类生成相应数据
* 应页面具体需求,从上级类中取得数据,生成需求的新html
* @author 小米布枪 artwc@qq.com
* Created:2011-11-03
* @param {String} 省.
* @param {String} 市.
* @param {String} 县.
* @param {Element} 包含整个个html的父节点.
* @return {void}
* @constructor
*/
function setArea(box,province,city,district) {
 //实例上级类,获得初始数据
 this.Are = new getArea(province,city,district);
 this.tag = [box.getElementsByTagName('dt'),box.getElementsByTagName('dd')];
 //初始化
 this.setAreaDat(0);
 /**
  * 给外层box添加闭包函数,判断触发事件tagName执行相关操作
  * return前有代码的话,会因函数后的(this)在初始的时候执行,并把代表当前类的obj以参数传入
  * return后的的代码将在有鼠标点击事件发生时才会执行
  * this指向鼠onclick事件源box
  * @param {Object} 当前类的引用
  * @return {Function} 执行弹出层和设置新html数据操作
  */
 box.onclick = function(areaObj) {
  /**
   * 闭包函数,也是此类实现无数个new的重点所在
   * 判断触发事件的tag,并执行相关操作
   * this通父级this,指向onclick的源 - box
   * @param {Event}
   */
  return function(e) {
   var evt = e||event, span = evt.srcElement||evt.target;
   var mName = span.parentNode.nodeName.toLowerCase();
   if(mName === 'dt') {
    for(var i = 0, j; j = areaObj.tag[1][i++];) j.style.display = 'none';
    span.parentNode.nextSibling.style.display = 'block';
   } else if(mName === 'dd') {
    span.parentNode.style.display = 'none';
    areaObj.setProvince(span);
   }
  }
 }(this);
}
/**
 * 将省市参数拿给主判断,生成新值改变HTML内容
 * @param {Number:[0,1,2]} 标示当前处理的省或市
 * @return {Void} 重新设置选择,以及相应的内容
 */
setArea.prototype.setAreaDat = function(a) {
 this.Name = [this.Are.pName,this.Are.cName,this.Are.dName];
 this.Dat = [this.Are.pDat,this.Are.cDat,this.Are.dDat];
 for(var i=a; i < 3; i++) {
  this.tag[0][i].getElementsByTagName('span')[0].innerHTML = this.Name[i];
  this.tag[0][i].getElementsByTagName('input')[0].value = this.Name[i];
  this.tag[1][i].innerHTML = this.createHTML(this.Dat[i],i);
 }
}
/**
 * 根据省市新的名称创建新的对应的数据
 * @param {Json} 属于当前省市的json节点
 * @param {Number[0,1,2]} 当前省市县层级标
 * @return {String} 生成的HTML数据
 */
setArea.prototype.createHTML = function(arr,a) {
 if(!arr.length){return '请先选择城市';}
 var html = '';
 for(var i = 0, j; j = arr[i++]; ) html += '<span rel="'+a+'">'+j+'</span>';
 return html;
}
/**
 * 设置当前选择县名称
 */
setArea.prototype.setDistrict = function(district) { this.Are.dName = district; }
/**
 * 鼠标点击后执行,重设HTML数据
 * @param {Event} 鼠标点击事件,用来取当前点击节点上存储的层级号和装载的省市名
 * @return {Void} 交由鼠标点击后执行数据重新设置操作
 */
setArea.prototype.setProvince = function(mouseTag) {
 var a = Number(mouseTag.getAttribute('rel'));
 var areaName = mouseTag.innerHTML;
 switch (a) {
  case 0: this.Are.getCity(areaName); break;
  case 1: this.Are.getDistrict(areaName); break;
  case 2: this.setDistrict(areaName); break;
 } this.setAreaDat(a);
}
</script>
<!--调用方法-->
<script type="text/javascript">
new locatArea(document.getElementById('citySelectTag'),"北京市","市辖区","东城区");
new locatArea(document.getElementById('citySelectTag2'));
</script>
<div style="padding:30px;clear:both;font-size:12px;color:gray;">
 <pre>
  呕心之作:历经几个日夜的思索终于造出这么一段可以自定皮肤可以无数new的select省市县三级联动<br>
  周折:<br>
  1.得是用鼠标事件来模拟菜单效果,所以想匿名new出多个实例变的尤其困难;
  2.为了精练代码html主要用innerHTML生成,在ff中遇到了innerHTML出的东西找不到父级的bug,解决许久(仔细看代码你会发现一行很??碌恼腋讣兜拇??;
  3.数据整理不容易,为了重用,专门为取出原始数据写了个对象,好给用纯select来实现时能够重用;
  4.代码刚刚完工,还没来的及深加工提练精减;
  5.使用了闭包,json数据已经压到最小33KB,如果要一个页面上new出1000个来,估计内存会吃不消.
 </pre>
</div>
</body>
</html>

class_area.js文件内容如下

 代码如下
function getArea(province,city,district){this.dat={"和田地区":["和田市","和田县","墨玉县","皮山县","洛浦县","策勒县","于田县","民丰县"],"伊犁哈萨克自治州":["伊宁市","奎屯市","伊宁县","察布查尔锡伯自治县","霍城县","巩留县","新源县","昭苏县","特克斯县","尼勒克县"],"塔城地区":["塔城市","乌苏市","额敏县","沙湾县","托里县","裕民县","和布克赛尔蒙古自治县"],"阿勒泰地区":["阿勒泰市","布尔津县","富蕴县","福海县","哈巴河县","青河县","吉木乃县"],"省直辖行政单位":["石河子市","阿拉尔市","图木舒克市","五家渠市"]},"台湾省":"台湾省","香港特别行政区":"","澳门特别行政区":""}
this.text=['选择省','选择市','选择县'];this.pName=this.text[0];this.cName=this.text[1];this.dName=this.text[2];this.pDat=[];this.cDat=[];this.dDat=[];var p=province||'',c=city||'',d=district||'';this.init(province||'选择省',city||'选择省',district||'选择省');}
getArea.prototype={init:function(p,c,d){if(typeof this.dat[p]==='object'){this.pName=p;for(var i in this.dat[p])this.cDat.push(i);if(typeof this.dat[p][c]==='object'){this.cName=c;this.dName=d;for(var i=0,j;j=this.dat[p][c][i++];)this.dDat.push(j);}}
for(var i in this.dat)this.pDat.push(i);},getCity:function(province){this.pName=province;this.cName=this.text[1];this.dName=this.text[2];this.cDat=[];this.dDat=[];var obj=this.dat[this.pName];for(var i in obj){this.cDat.push(i);}},getDistrict:function(city){this.cName=city;this.dName=this.text[2];this.dDat=[];var obj=this.dat[this.pName][this.cName];for(var i=0,j;j=obj[i++];)
this.dDat.push(j);}}

精彩图集

赞助商链接