自定义select皮肤的三级联动下拉菜单
这里提供一款自定义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);}} |
精彩图集
精彩文章