代码:
/*
*
* oSelect v1.0 联动列表类
*
* Author: Winder
* Email: [email protected]
* Date: 2006/04/30
* Version: 1.0
*
* 调用接口:
*
* addOption(text, value, selected) 增加列表选项数据
* addOptionsArray(arrOptions) 以数组方式批量载入列表选项
* Link(Select) 联选项到子列表对象
* Create(ID) 创建列表对象
* loadXML(xmlFile) 加载XML文件为列表数据
*
* 示例:
* 见后。
*
*/function oSelect(name, id, action, Options, xmlOptions){
this.name = name; // 列表对象名称
this.id = id; // 列表位置 this.Options = new Array(); //列表选项,多维数组
this.xmlOptions = xmlOptions; //列表选项,加载XML数据 this.index = -1; // 对象关联层次,设置为-1,为使得第一个选项为0
this.Links = new Array(); // 选项关联对象 this.Created = false; // 列表创建标志:默认--未创建;1--原来不存在,新建立;2--原来存在,增加选项的
this.Select = null; // 列表对象
this.parent = null; // 父列表对象
this.child = null; // 子列表对象 this.action = action; // 处理列表对象选项
if ( Options )
this.addOptionsArray( Options );
// 从XML文件中加载选项数据
if ( xmlOptions )
this.loadXML( xmlOptions );
}// 增加选项数据
oSelect.prototype.addOption = function(text, value, selected){
// text 选项文本
// value 选项值
// selected 选项选中状态
if ( !text ) return;
// 变量判断:存在,为空,为0,为false
value = ( value ) ? value : text;
selected = ( selected && selected != "false" ) ? true : false;
this.index += 1; // 关联索引
this.Options[this.index] = Array(text, value, selected);
}
// 以数组方式批量载入列表选项
oSelect.prototype.addOptionsArray = function( arrOptions ){
if ( typeof(arrOptions)=="string" )
arrOptions = new Array(arrOptions);
for ( var i=0; i<arrOptions.length; i++ ){
var aOption = arrOptions[i];
if ( typeof(aOption)=="string" )
aOption = new Array(aOption);
var aText = aOption[0]; // 选项文本
var aValue = aOption[1]; // 选项值
var aSelected = aOption[2]; // 选项选中状态
// 增加选项数据
this.addOption( aText, aValue, aSelected );
// 下一级列表数组
var rOption = aOption[3];
if ( rOption ){
// name
var oID = this.id;
var oAction = this.action;
var _Select = new oSelect( "", oID, oAction );
_Select.addOptionsArray( rOption );
// 关联子列表对象
this.Link( _Select );
}
}
}
// 关联选项到子列表对象
oSelect.prototype.Link = function( oS ){
if ( !oS ) return;
this.Links[this.index] = oS;
}
// 创建列表对象
oSelect.prototype.Create = function( id ){
// 列表位置
this.id = ( id ) ? id : this.id; // 列表名称
var name = this.name;
// 判断该名称对象是否存在
// 已经存在,则采用该列表对象,不再新建立
if ( name && typeof(name)=="object" && name.tagName=="SELECT" ){
var oS = name;
this.Created = 2;
}else if( name && document . getElements ByName( name ) && document . getElements ByName( name )[0] ){
var oS = document . getElements ByName( name )[0];
this.Created = 2;
}else{
var S = "<SELECT";
if ( name )
S += " name='" + name + "'";
S += ">";
S += "</SELECT>";
var oS = document.createElement( S ); // 确定对象位置
if ( typeof( this.id ) == "string" ){
// 得到位置对象
this.id = document.getElementById ( this.id );
}
if( this.id ){
// 在指定位置对象最后插入列表对象
var objS = this.id.insertBefore( oS );
this.Created = 1;
}else if( this.parent && typeof(this.parent) == "object" ){
// 父列表对象存在,作为子列表对象,插入到父对象后面
var objS = this.parent.Select.parentNode.insertBefore( oS );
this.Created = 1;
}else{
// Void
}
} // 设定相关属性定义
// 该类没办法继承给onchange方法,暂且采用SELECT传递类对象
// * 注意 *
oS.__mSelect = this;
// 列表对象
this.Select = oS; // 绑定行为
oS.onchange = this.Change; // 添加列表选项
if ( this.Options.length > 0 )
this.createOptions( );
}// 清除子对象列表
oSelect.prototype.Remove = function(){
var obj = this;
if ( obj ){
// 循环删除下一级列表
var oChild = obj.child;
if ( oChild ){
oChild.Remove( );
} // 判断对象创建状态
// 列表对象已经存在,则先清楚原来列表对象
// 原来列表为:
// 1--原来不存在,新建的
// 2--原来存在,增加选项的
// 其它--还不存在
var isCreated = obj.Created;
if ( isCreated == 2 ){
// 原来存在,增加选项的,重置选项
var oSelect = obj.Select;
var oOptions = oSelect.options;
for ( var i = 0; i < oOptions.length; i ++ ){
var oOption = oOptions[i];
// 以__index属性判断选项是否为类创建
// alert( "oOption:" + oOption.outerHTML );
if ( oOption.__index >= 0 ){
oSelect.remove( i );
// oSelect.options[i] = null;
}
}
}else
// 原来不存在,新建的,则删除对象
obj.Select.removeNode(true);
}
}// 改变列表选项
oSelect.prototype.Change = function(){
// 取得SELECT对象
var sObj = this; // 取得类继承
var thisMe = this.__mSelect; // alert(thisMe.name);
// 获取选项索引
// * 该处this为select对象
var sIndex = sObj.selectedIndex;
// 当前选项对象
var oOption = sObj.options[sIndex];
// 本类创建的选项索引
var oIndex = oOption.__index;
// alert("sIndex:" + sIndex + "|" + oIndex); // 执行指定函数
if ( thisMe.action ){
try
{
// 执行指定函数
thisMe.action ( sObj.options[sIndex].value );
}
catch ( e )
{
// Void
}
} // 清除子对象
var oChild = thisMe.child;
if ( oChild ){
oChild.Remove( );
} // 该选项关联对象
var oLink = thisMe.Links[oIndex];
if ( oLink ){
// 设置子对象关联
thisMe.child = oLink;
oLink.parent = thisMe;
// 创建关联对象
oLink.Create();
}
}// 创建列表选项
oSelect.prototype.createOptions = function( ){
var Options = this.Options;
if ( !Options ) return;
if (typeof(Options) == "string")
Options = new Array( Options );
var oS = this.Select;
if ( !oS )
return;
for ( i=0; i<Options.length; i++ ){
var aOption = Options[i];
if ( !aOption ) continue;
if ( typeof(aOption)=="string" )
aOption = new Array(aOption);
var txtText = aOption[0]; //选项文本
var txtValue = aOption[1]; //选项值
txtValue = ( txtValue ) ? txtValue : txtText;
var bSelected = ( aOption[2] ) ? true : false;
var oOption = new Option(txtText.toString(), txtValue.toString());
// oOption.selected = true;
// 选项索引
oOption.__index = i;
oS.options.add(oOption);
oS.options[oS.length-1].selected = bSelected;
}
}
/*
*
* oSelect v1.0 联动列表类
*
* Author: Winder
* Email: [email protected]
* Date: 2006/04/30
* Version: 1.0
*
* 调用接口:
*
* addOption(text, value, selected) 增加列表选项数据
* addOptionsArray(arrOptions) 以数组方式批量载入列表选项
* Link(Select) 联选项到子列表对象
* Create(ID) 创建列表对象
* loadXML(xmlFile) 加载XML文件为列表数据
*
* 示例:
* 见后。
*
*/function oSelect(name, id, action, Options, xmlOptions){
this.name = name; // 列表对象名称
this.id = id; // 列表位置 this.Options = new Array(); //列表选项,多维数组
this.xmlOptions = xmlOptions; //列表选项,加载XML数据 this.index = -1; // 对象关联层次,设置为-1,为使得第一个选项为0
this.Links = new Array(); // 选项关联对象 this.Created = false; // 列表创建标志:默认--未创建;1--原来不存在,新建立;2--原来存在,增加选项的
this.Select = null; // 列表对象
this.parent = null; // 父列表对象
this.child = null; // 子列表对象 this.action = action; // 处理列表对象选项
if ( Options )
this.addOptionsArray( Options );
// 从XML文件中加载选项数据
if ( xmlOptions )
this.loadXML( xmlOptions );
}// 增加选项数据
oSelect.prototype.addOption = function(text, value, selected){
// text 选项文本
// value 选项值
// selected 选项选中状态
if ( !text ) return;
// 变量判断:存在,为空,为0,为false
value = ( value ) ? value : text;
selected = ( selected && selected != "false" ) ? true : false;
this.index += 1; // 关联索引
this.Options[this.index] = Array(text, value, selected);
}
// 以数组方式批量载入列表选项
oSelect.prototype.addOptionsArray = function( arrOptions ){
if ( typeof(arrOptions)=="string" )
arrOptions = new Array(arrOptions);
for ( var i=0; i<arrOptions.length; i++ ){
var aOption = arrOptions[i];
if ( typeof(aOption)=="string" )
aOption = new Array(aOption);
var aText = aOption[0]; // 选项文本
var aValue = aOption[1]; // 选项值
var aSelected = aOption[2]; // 选项选中状态
// 增加选项数据
this.addOption( aText, aValue, aSelected );
// 下一级列表数组
var rOption = aOption[3];
if ( rOption ){
// name
var oID = this.id;
var oAction = this.action;
var _Select = new oSelect( "", oID, oAction );
_Select.addOptionsArray( rOption );
// 关联子列表对象
this.Link( _Select );
}
}
}
// 关联选项到子列表对象
oSelect.prototype.Link = function( oS ){
if ( !oS ) return;
this.Links[this.index] = oS;
}
// 创建列表对象
oSelect.prototype.Create = function( id ){
// 列表位置
this.id = ( id ) ? id : this.id; // 列表名称
var name = this.name;
// 判断该名称对象是否存在
// 已经存在,则采用该列表对象,不再新建立
if ( name && typeof(name)=="object" && name.tagName=="SELECT" ){
var oS = name;
this.Created = 2;
}else if( name && document . getElements ByName( name ) && document . getElements ByName( name )[0] ){
var oS = document . getElements ByName( name )[0];
this.Created = 2;
}else{
var S = "<SELECT";
if ( name )
S += " name='" + name + "'";
S += ">";
S += "</SELECT>";
var oS = document.createElement( S ); // 确定对象位置
if ( typeof( this.id ) == "string" ){
// 得到位置对象
this.id = document.getElementById ( this.id );
}
if( this.id ){
// 在指定位置对象最后插入列表对象
var objS = this.id.insertBefore( oS );
this.Created = 1;
}else if( this.parent && typeof(this.parent) == "object" ){
// 父列表对象存在,作为子列表对象,插入到父对象后面
var objS = this.parent.Select.parentNode.insertBefore( oS );
this.Created = 1;
}else{
// Void
}
} // 设定相关属性定义
// 该类没办法继承给onchange方法,暂且采用SELECT传递类对象
// * 注意 *
oS.__mSelect = this;
// 列表对象
this.Select = oS; // 绑定行为
oS.onchange = this.Change; // 添加列表选项
if ( this.Options.length > 0 )
this.createOptions( );
}// 清除子对象列表
oSelect.prototype.Remove = function(){
var obj = this;
if ( obj ){
// 循环删除下一级列表
var oChild = obj.child;
if ( oChild ){
oChild.Remove( );
} // 判断对象创建状态
// 列表对象已经存在,则先清楚原来列表对象
// 原来列表为:
// 1--原来不存在,新建的
// 2--原来存在,增加选项的
// 其它--还不存在
var isCreated = obj.Created;
if ( isCreated == 2 ){
// 原来存在,增加选项的,重置选项
var oSelect = obj.Select;
var oOptions = oSelect.options;
for ( var i = 0; i < oOptions.length; i ++ ){
var oOption = oOptions[i];
// 以__index属性判断选项是否为类创建
// alert( "oOption:" + oOption.outerHTML );
if ( oOption.__index >= 0 ){
oSelect.remove( i );
// oSelect.options[i] = null;
}
}
}else
// 原来不存在,新建的,则删除对象
obj.Select.removeNode(true);
}
}// 改变列表选项
oSelect.prototype.Change = function(){
// 取得SELECT对象
var sObj = this; // 取得类继承
var thisMe = this.__mSelect; // alert(thisMe.name);
// 获取选项索引
// * 该处this为select对象
var sIndex = sObj.selectedIndex;
// 当前选项对象
var oOption = sObj.options[sIndex];
// 本类创建的选项索引
var oIndex = oOption.__index;
// alert("sIndex:" + sIndex + "|" + oIndex); // 执行指定函数
if ( thisMe.action ){
try
{
// 执行指定函数
thisMe.action ( sObj.options[sIndex].value );
}
catch ( e )
{
// Void
}
} // 清除子对象
var oChild = thisMe.child;
if ( oChild ){
oChild.Remove( );
} // 该选项关联对象
var oLink = thisMe.Links[oIndex];
if ( oLink ){
// 设置子对象关联
thisMe.child = oLink;
oLink.parent = thisMe;
// 创建关联对象
oLink.Create();
}
}// 创建列表选项
oSelect.prototype.createOptions = function( ){
var Options = this.Options;
if ( !Options ) return;
if (typeof(Options) == "string")
Options = new Array( Options );
var oS = this.Select;
if ( !oS )
return;
for ( i=0; i<Options.length; i++ ){
var aOption = Options[i];
if ( !aOption ) continue;
if ( typeof(aOption)=="string" )
aOption = new Array(aOption);
var txtText = aOption[0]; //选项文本
var txtValue = aOption[1]; //选项值
txtValue = ( txtValue ) ? txtValue : txtText;
var bSelected = ( aOption[2] ) ? true : false;
var oOption = new Option(txtText.toString(), txtValue.toString());
// oOption.selected = true;
// 选项索引
oOption.__index = i;
oS.options.add(oOption);
oS.options[oS.length-1].selected = bSelected;
}
}
oSelect.prototype.loadXML = function( xmlFile ){
var oXml = new ECMXml( ); // 同步请求选项数据
var oData = oXml.LoadXML( xmlFile );
this.loadOptionsXML( oData );
/*
// 异步请求选项数据
oXml.Ajax( xmlFile, this.loadOptionsXML, this );
*/
}// 解析XML数据加载为选项
oSelect.prototype.loadOptionsXML = function( xmlData, thisSelect ){
var thisS = ( thisSelect ) ? thisSelect[0] : this;
if ( !xmlData )
return;
var oRoot = xmlData.documentElement;
if ( !oRoot )
return;
// 加载对象标志,用于对选项XML数据的分析规则
// 1、必须先加载列表,才能加载选项
// 2、子列表必须与某一选项关联,即鼻祖在加载某一选项后加载
// 初始列表对象已经由类创建
thisS._loadSelect = true;
thisS._loadOption = false; // 加载数据
thisS.loadOption( oRoot, thisS);
}// 加载XML节点为选项数据
oSelect.prototype.loadOption = function( oData, thisSelect ){
var thisS = ( thisSelect ) ? thisSelect : this; if ( !oData ) return;
var oTagName = oData.tagName;
// 列表标签
if ( oTagName == "SELECT" ){
var oName = oData.getAttribute("name");
var oID = oData.getAttribute("id");
oID = ( oID ) ? oID : thisS.id ;
var oAction = oData.getAttribute("action");
oAction = ( oAction ) ? oAction : thisS.action;
if ( thisS._loadSelect && !thisS._loadOption ){
// 列表已经存在
oName = ( oName ) ? oName : thisS.name ;
thisS.name = oName;
thisS.id = oID;
thisS.action = oAction;
}else{
if ( thisS._loadOption ){
// 已经存在选项,则关联到子列表
var _Select = new oSelect( oName, oID, oAction );
thisS.Link( _Select );
thisS = _Select;
thisS._loadSelect = true;
thisS._loadOption = false;
}else{
// 新建立列表
/* 这种情况应当是不允许存在,因为这样没办法把本类返回,未进一步严格测试。 */
var _Select = new oSelect( oName, oID, oAction );
thisS = _Select;
thisS._loadSelect = true;
thisS._loadOption = false;
}
}
}
// 选项标签
if ( oTagName == "OPTION" ){
if ( thisS._loadSelect ){
// 列表已经存在,则加载选项
var oText = oData.getAttribute("text");
oText = ( oText ) ? oText : oData.text ;
var oValue = oData.getAttribute("value");
var oSelected = oData.getAttribute("selected");
// 加载选项
thisS.addOption( oText, oValue, oSelected );
thisS._loadOption = true;
}else{
// 列表不存在,无法加载选项,忽略本节点
}
}
// 递归读取子节点
var oChilds = oData.childNodes;
for (var i = 0; i < oChilds.length; i++) {
var oChild = oChilds[i];
thisS.loadOption( oChild, thisS );
}
}/*
* XML 操作类
* 引用并修改至FCKeditor中的FCKXml类
* LoadXML(url) 以同步请求载入XML文件
* LAjax(url, call) 以异步请求载入XML文件
*/
function ECMXml()
{
this.Error = false ;
}// 同步请求方式载入XML文件
ECMXml.prototype.LoadXML = function( url )
{
this.url = url; var oXmlHttp = this.CreateXMLHttp( ); if ( !oXmlHttp )
{
this.Error = true ;
return ;
} oXmlHttp.open( "GET", this.url, false ) ; oXmlHttp.send( null ) ;
if ( oXmlHttp.status == 200 || oXmlHttp.status == 304 )
this.DOMDocument = oXmlHttp.responseXML ;
else if ( oXmlHttp.status == 0 && oXmlHttp.readyState == 4 )
{
this.DOMDocument = this.CreateXMLDoc( ) ;
// this.DOMDocument.async = false ;
// this.DOMDocument.resolveExternals = false ;
// this.DOMDocument.loadXML( oXmlHttp.responseText ) ;
try{
this.DOMDocument.load( this.url );
}catch( e ){
this.Error = true ;
this.DOMDocument = null;
}
}
else
{
this.Error = true ;
alert( 'Error loading "' + this.url + '"' ) ;
}
return this.DOMDocument;
}// 异步请求方式载入XML文件
ECMXml.prototype.Ajax = function( url, call )
{
this.url = url;
this.Error = false ;
this.call = call;
this.arguments = new Array();
var j = 0;
for ( i = 2; i < arguments.length; i ++)
{
this.arguments[j] = arguments[i];
j += 1;
}
var varArguments = this.arguments; // return; var oXmlHttp = this.CreateXMLHttp( ); if ( !oXmlHttp )
{
this.Error = true ;
return ;
}
this.oXmlHttp = oXmlHttp; oXmlHttp.onreadystatechange = function () {
ECMXml._OnReadyStateChange(oXmlHttp, call, varArguments );
}; oXmlHttp.open( "GET", this.url, true ) ; // 发送数据
oXmlHttp.send( null );
/*
window.setTimeout(function () {
oXmlHttp.send(null);
}, 10);
*/
}// 监听XML文档对象状态,响应请求事件
ECMXml._OnReadyStateChange = function( xmlHttp, funCall )
{
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
// 额外参数传递
var varArguments = arguments[2];
funCall( xmlHttp.responseXML, varArguments);
} else {
// Void
}
}
}// 创建XmlHttp请求
ECMXml.prototype.CreateXMLHttp = function( )
{
try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {}
try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {}
try { return new XMLHttpRequest(); } catch(e) {}
return null;
}// 创建对象
ECMXml.prototype.CreateXMLDoc = function( )
{
try { return new ActiveXObject("MSXML2.DOMDocument"); } catch(e) {}
try { return new ActiveXObject("Microsoft.XmlDom"); } catch(e) {}
try { return document.implementation.createDocument( '', '', null ); } catch(e) {}
return null;
}
// 获取XML数据
ECMXml.prototype.GetXml = function( )
{
return this.DOMDocument;
}
<HTML>
<HEAD>
<TITLE> oSelect v1.0 </TITLE>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="winder">
<META NAME="Keywords" CONTENT="联动列表 类">
<META NAME="Description" CONTENT="联动列表类">
<script type="text/javascript" language="JavaScript 1.2" src="oSelect.js"></script>
</HEAD><BODY><SELECT name="SNAME">
<option value="OK">已经</option>
</SELECT>
<SELECT name="SNAME2">
<option value="OK2">已经</option>
</SELECT>
<span id="SID">
</span><script type="text/javascript" language="JavaScript 1.2">
/*
* 使用例子
*/
/*
// 数据定义方式一:
var mySelect =
[
//格式:[选项, 选项值, 默认状态:true--选中]
['选项1.1', '1.1', false,
[
['选项2.1', '2.1', true],
['选项2.2', '2.2', '',
[
['选项3.1', '3.1', ''],
['选项3.2', '3.2', true]
]
],
['选项2.3', '2.3', '']
]
],
['选项1.2', '1.2', true],
['选项1.3', '1.3', '']
];
*/// 数据定义方式二:
var mySelect = new Array();
mySelect[0] = Array('选项1.1', '1.1', false);
mySelect[0][3] = Array();
mySelect[0][3][0] = Array('选项2.1', '2.1', true);
mySelect[0][3][1] = Array('选项2.2', '2.2', '');
mySelect[0][3][1][3] = Array();
mySelect[0][3][1][3][0] = Array('选项3.1', '3.1', '');
mySelect[0][3][1][3][1] = Array('选项3.2', '3.2', true);
mySelect[0][3][2] = Array('选项2.3', '2.3', '');
mySelect[1] = Array('选项1.2', '1.2', true);
mySelect[2] = Array('选项1.3', '1.3');// 例子一
// var S = new oSelect(SNAME, 'SID', mySelect);
// S.Create( ); // 输出创建// 例子二
/*
var S = new oSelect('SNAME');
var O = S.addOption("---", "");
var O = S.addOption("Text", "Value");
var S1 = new oSelect( 'SNAME2');
var O1 = S1.addOption("选项2.1", "2.1");
S.Link( S1 );
S.action = isS; // 对象onchange 执行函数
S.Create( "SID" ); // 输出创建
*/// 例子三
/*
var S = new oSelect('SNAME');
S.addOptionsArray(mySelect); // 载入Select选项数组
S.action = isS; // 对象onchange 执行函数
S.Create( "SID" ); // 输出创建
*/// 例子四
var S = new oSelect('SNAME');
S.action = isS; // 对象onchange 执行函数
S.loadXML( 'S.xml' + '?time=' + new Date().getTime() ); // 载入Select选项XML文件
S.Create( "SID" ); // 输出创建function isS( s ){
alert( s );
}
</script></BODY>
</HTML>
谢谢!另,
由于:本论坛提示我,document . getElements ByName (去掉空格会给论坛带来伤害),
所以,复制使用,需要将document . getElements ByName中的空格去除。希望:
希望各位共同:
1、完善功能;
2、优化结构、性能;
3、触类旁通,交流、讨论有关知识。
S.xml的格式
===========================================
<?xml version="1.0" encoding="gb2312" ?>
<SELECT name="cit">
<SELECT>
<OPTION value="1.1" selected="true">选项1.1</OPTION>
<OPTION value="1.2" text="选项1.2">
<SELECT name="">
<OPTION value="2.1" text="选项2.1" selected="false">
<SELECT name="">
<OPTION value="3.1" text="选项3.1" selected="false">
</OPTION>
<OPTION value="3.2">选项3.2</OPTION>
<OPTION value="3.3" selected="true">选项3.3</OPTION>
<OPTION value="3.4" selected="false">选项3.4</OPTION>
</SELECT>
</OPTION>
<OPTION value="2.2" text="选项2.2">
<SELECT name="">
<OPTION value="3.2.1" text="选项3.2.1" selected="false">
</OPTION>
<OPTION value="3.2.2">选项3.2.2</OPTION>
<OPTION value="3.2.3" selected="true">选项3.2.3</OPTION>
<OPTION value="3.2.4" selected="false">选项3.2.4</OPTION>
</SELECT>
</OPTION>
<OPTION value="2.3" selected="true">选项2.3</OPTION>
<OPTION value="2.4" selected="true">选项2.4</OPTION>
</SELECT>
</OPTION>
<OPTION value="1.3">选项1.3</OPTION>
</SELECT>
</SELECT>
To:JK_10000
我也觉得有点长。
因为提供了多个数据载入接口,导致方法比较多,能否:
1、就实现方法上提供一些指导?
2、就程序实现上和算法上提供一些优化的建议?
谢谢!