`

淘宝javascript类别多级下拉连动解析和改进

阅读更多


效果地址:
http://search1.taobao.com/browse/ad_search.htm

具体代码见: 附件1

其中关键代码解析:

 

一、构造类别数组
声明一个类别数组cat

 

cats['11']=['电脑硬件/台式整机/网络设备','1'];
cats['110502']=['品牌液晶显示器','11'];
cats['110202']=['内存','11'];

 

 


5000多个略…,规则为:
数组的下标是类别id,
第一个元素为类别名
第二个元素为类别父id

接下来构一个将cats数组存入一个parent数组,数组的下标为cats数组的父id,元素为类别数组本身:

 

for (c in cats) {
	var ii =  cats[c][1];
	if (!parent[ii]) {
		parent[ii] = new Array();
	}
	parent[ii][parent[ii].length] = c;
}

 

 

 

这样,形成如下图的两个类别数组:

 

 

二、填充下拉框方法
利用cats 和parent两个数组填充,主要是得到了选中的某个类别的子类别集合:

 

 

 

/*
id:选中的类别id
obj:下拉列表框dom对象
defaultId: 如果要选中默认的某个子,则传递此参数
isFirst:为了可以连级初始化所用。
*/
function _addList(id, obj, defaultId, isFirst) {
	if (!defaultId) {
		defaultId = -1;
	}
	
	var s = 0;
	if (haveBlank == 'true') {
		obj.options[s++] = new Option('', '');
	}

	if (parent[id]) { //利用上面的数组关系直接得到了子数组
		for (var i = 0; i < parent[id].length; ++i) {
			var catId = parent[id][i];//某个子的id
			if (!parent[catId]) {  
				obj.options[s++] = new Option(cats[catId][0], catId);
			}else {
				obj.options[s++] = new Option(cats[catId][0] + ' ->', catId); //如果还有子显示一个"->"
			}
			if (defaultId >= 0 && defaultId == catId) {
				obj.options[s-1].selected = true;
				changeSubCat(obj);
			}else if (i == 0 && !isFirst && haveBlank == '') {
				obj.options[i].selected = true;
				changeSubCat(obj);
			}
		}
	}

}

 


三、填充下拉框的子下拉框


其中做了一些判断是否有子,是否有子下拉框。

 

 

function changeSubCat(obj) {
	if (!obj || !obj.name) {
		error('obj not found!');
		return;
	}
	var name = obj.name;
	var form = document.forms[formName];
	if (!form) {
		error('form not found!');
		return;
	}
	

	var selectNum = -1;
	for (var i = 0; i < catSel.length; ++i) {
		if (catSel[i] == name) {
			selectNum = i;
			break;
		}
	}
	if (selectNum < 0) {
		debug('can\'t found sub select');
		_setValue();	
		return;
	}
	if (selectNum + 1 >= catSel.length || !form.elements[catSel[selectNum + 1]]) {
		debug('can\'t found sub select 1');
		_setValue();
		return;
	}
	var subSel = form.elements[catSel[selectNum + 1]];
	_clearList(subSel);
	
	for (var i = selectNum + 1; i < catSel.length; ++i) {
		if (form.elements[catSel[i]]) {
			_clearList(form.elements[catSel[i]]);
		}
	}
	
	if (obj.options[obj.selectedIndex].value == '') {
		_setValue();
		return;
	}

	var catId = obj.options[obj.selectedIndex].value;
	if (!parent[catId]) {
		debug('no sub select data');
		_setValue();
		return;
	}
	_addList(catId, subSel);
	_setValue();
}

 

 

 


如上方法可实现了多级下拉框连动,不过有以下问题:

1. 和form绑定死了
2. 在一个页面无法存在多个连动下拉框
3. 下拉框的name不能自定义,

在项目中同样有此需求,需要同时使用多个连动下拉框,同时name也需自定义,稍改进了一下,将各种方法和数组放入类中,同时根据下拉框的id来绑定下拉框,集成了下拉框的onchagne事件

 

function TreeSelect(){
	
	this.haveBlank=undefined;
	this.cats=undefined;
	this.parent=undefined;
	/**
	 * 初始化数据
	 */
	this.init= function(_cats,_haveBlank,_selid){
		this.cats= _cats;
		this.initParnet(_cats);
		this.haveBlank=_haveBlank;
		this.initSelObj(_selid);
		
	};
	
	
	
	/**
	 * 初始化select对象数组
	 */
	this.initSelObj=function(_selid){
		var p = this;
		function fireChangeEvent(){
			p.changeSubCat(event.srcElement);
		}
		
		
		this.catSel = _selid.split(',');
		this.sel_ar = new Array();
		for(var i=0;i<this.catSel.length;i++){
			this.sel_ar[i] = document.getElementById(this.catSel[i]);	
			this.sel_ar[i].attachEvent('onchange',fireChangeEvent,true);
		}	
		
		
	};
	
 
	
	
	/**
	 * 初始化树数据数组
	 */
	this.initParnet=function(cats){
		this.parent = new Array();
		for (c in cats) {
			var ii =  cats[c][1];
			if (!this.parent[ii]) {
				this.parent[ii] = new Array();
			}
			this.parent[ii][this.parent[ii].length] = c;
		}
	};
	
	
	
	
	
	/**
	 * 清空select列表
	 */
	this._clearList=function(obj) {
		if (!obj) {
			return;
		}
		for (var i = obj.length - 1; i >= 0; --i) {
			obj.remove(i);
		}
		obj.value = '';
	}
	;
	
	
	
	
	
	/**
	 * 改变子的选择
	 */
	this.changeSubCat=function(obj) {
		if (!obj || !obj.id) {
			error('obj not found!');
			return;
		}
		var name = obj.id;
	
		var selectNum = -1;
		for (var i = 0; i < this.catSel.length; ++i) {
			if (this.catSel[i] == name) {
				selectNum = i;
				break;
			}
		}
		if (selectNum < 0) {
			debug('can\'t found sub select');
		
			return;
		}
		if (selectNum + 1 >= this.catSel.length || !document.getElementById( this.catSel[selectNum + 1] )) {
			debug('can\'t found sub select 1');
			return;
		}
		var subSel = document.getElementById(this.catSel[selectNum + 1]);
		this._clearList(subSel);
		
		for (var i = selectNum + 1; i < this.catSel.length; ++i) {
			if (document.getElementById([this.catSel[i]])) {
				this._clearList(document.getElementById(this.catSel[i]));
			}
		}
		
	
		var catId = obj.options[obj.selectedIndex].value;
		if (!this.parent[catId]) {
			debug('no sub select data');
			 
			return;
		}
		this._addList(catId, subSel);
	 
	};
	
	
	/**
	 * 填充一个select
	 */
	this._addList=function(id, obj, defaultId, isFirst) {
		if (!defaultId) {
			defaultId = -1;
		}
		
		var s = 0;
		if (this.haveBlank == 'true') {
			obj.options[s++] = new Option('请选择', ''); 
		}
	
		if (this.parent[id]) {//当前选中的子数组
			for (var i = 0; i < this.parent[id].length; ++i) {
				var catId = this.parent[id][i];
				if (!this.parent[catId]) {
					obj.options[s++] = new Option(this.cats[catId][0], catId);
				}else {
					obj.options[s++] = new Option(this.cats[catId][0] + ' ->', catId);
				}
				
				if (defaultId >= 0 && defaultId == catId) {
					obj.options[s-1].selected = true;
					this.changeSubCat(obj);
				}else if (i == 0 && !isFirst && this.haveBlank == '') {
					obj.options[i].selected = true;
					this.changeSubCat(obj);
				}
			}
		}
	
	};

}


function debug(info) {
	//alert(info);
}

function error(info) {
	alert(info);
}

 

 

 

详见: 附件2

 

实际项目中需要和数据库结合起来,通过标签输出,下面附件内容供大家参考:

附件3

 

  • 大小: 19.4 KB
3
2
分享到:
评论
1 楼 qustmao 2009-01-03  
谢谢分享,,,,,正好项目中要用到这个东西,去淘宝研究了很长时间,没有分离出js文件,,,,我在js方面就是个小白,,,,,,

相关推荐

    JSP、Java实现选择框多级连动

    实现选择框多级连动需要使用 JSP 和 Java technologies,并结合 Struts 框架和 JavaScript 代码来实现。在开发过程中,需要注意数据库表的设计、表单 bean 的设计、服务器端的数据处理和返回等方面。

    短信发送平台Demo js多级连动.

    综上所述,这个“短信发送平台Demo js多级连动”项目涵盖了JavaScript基础、前端交互设计、数据处理和响应式布局等多个方面,是一个实践Web开发技能的好案例。开发者可以通过这个Demo学习和掌握这些关键技术,并应用...

    连动下拉

    "连动下拉"是一种常见的用户界面交互设计,通常用于多级选择场景,如地区选择、类别筛选等。用户在一级菜单中选择一项后,二级菜单会根据一级选择动态更新其选项,以此类推。这种设计能有效节省屏幕空间,提高用户...

    多级连动如省份城市的选择连动,就如你选择福建这是另一个下拉框就会随你选择的省份对应的弹跳出城市,如你选择福建对应的厦门,福州,泉州,晋江,漳州,武夷山等等

    标题和描述提到的"多级连动如省份城市的选择连动",正是这种交互模式的一个具体实例,主要用于实现用户在选择一个地区(如省份)后,自动更新下一个地区级别(如城市)的选项,以显示与所选省份对应的城市列表。...

    ajax实现三级连动

    【Ajax实现三级联动】是指在Web开发中,利用Ajax技术实现多级下拉菜单之间的联动效果,例如在省、市、区的选择中,当用户在一级下拉菜单(如省份)中选择一个选项时,二级下拉菜单(如城市)会自动更新与之相关的...

    JS多级连动菜单

    **JS多级连动菜单**,即通过JavaScript技术来实现多个下拉选择框之间的联动。第一个下拉框(称为一级菜单)的变化会影响到第二个下拉框(称为二级菜单)中的选项,以此类推,可以有多级的联动。通常,这种联动是单向...

    javascript经典例子.txt

    - 实现方法:通过JavaScript操作DOM元素,实现添加、修改和删除下拉列表项的功能。 - **2.3 可以输入内容的下拉框** - 描述:实现一个支持输入搜索的下拉列表。 - 实现方法:使用JavaScript监听用户的输入事件,...

    angularjs和bootstrap开发的web控件的集合

    AngularJS,一个由Google维护的JavaScript框架,专注于数据绑定和依赖注入,使得前端开发更加模块化和易于维护。而Bootstrap,则是Twitter推出的一款用于快速构建响应式和移动优先网站的前端框架,它提供了丰富的UI...

    省市二级连动下拉框(JS+XML)

    本案例中,开发人员选择使用 **JavaScript (JS)** 和 **XML** 来实现省市二级联动下拉框功能。这种方式的优点是不需要服务器端的支持,只需要前端技术就可以完成,因此具有很好的灵活性和轻量性。 #### 三、XML文件...

    支持无限级的联动下拉菜单

    联动下拉菜单,又称为级联菜单或连动菜单,是指当用户在一个下拉菜单中选择某个选项时,会触发另一个下拉菜单的显示或更新。这种设计可以有效节省页面空间,提高用户体验,尤其在处理多级分类时。 二、无限级联动的...

    javascript代码常用大全

    ### JavaScript代码常用大全知识点解析 #### 一、验证类 **1. 数字验证** - **1.1 整数验证** - 目的是确保输入的字符串仅包含整数。 - 可以通过正则表达式 `/^-?\d+$/.test(str)` 实现,其中 `-?` 表示可选的...

    AJAX 做3级连动

    这里我们关注的是如何利用AJAX实现三级联动的效果,即在一个下拉菜单中选择一项时,相关的第二级和第三级下拉菜单会根据选择自动更新其内容。这在如地区选择、产品分类等场景中非常常见。 首先,我们需要理解AJAX的...

    实用javascript给力文档

    - **下拉菜单**:实现多级下拉菜单。 - **动态效果**:为状态栏和标题栏添加动态效果。 ##### 树型结构 树型结构用于表示层级关系的数据结构。 - **ASP+SQL 版本**:基于ASP和SQL Server构建的树型结构。 - **ASP+...

    dojo处理三级连动

    在IT行业中,Dojo是一个强大的JavaScript工具包,它提供了丰富的功能和组件,帮助开发者构建复杂的Web应用程序。在处理用户界面交互时,特别是涉及到多级联动的场景,Dojo的威力尤为显著。本篇文章将深入探讨如何...

    ASP三级联动1个表(带后台)

    总结起来,"ASP三级联动1个表(带后台)"是一个涉及服务器端脚本、数据库操作、前端交互和响应式设计的综合项目,通过合理组织和处理数据,实现了高效、动态的多级联动效果。这个项目对于学习ASP开发和Web交互设计来说...

    jquery基于layui实现二级联动下拉选择(省份城市选择)

    在本文中,我们将探讨如何使用jQuery和layui框架来实现二级联动下拉选择,特别是针对省份和城市的选择。layui是一款流行的前端UI框架,它提供了丰富的组件和API,使得开发者能够快速构建美观且响应式的Web应用。在...

Global site tag (gtag.js) - Google Analytics