最近用javacript写了一个模拟下拉列表的类
DivUlLiList.js // 类名:DivUlLiList // 作者:李晓亮 // 公司:上海兴侯科技 // 版本:V0.5 // 注意事项: // 1)在window.onload事件外进行对象声明 // 2)在window.onload事件中进行对象构建 // 3)附加控件仅支持文本框 function ListItem(itemText, itemValue){ this .itemText = itemText; this .itemValue = itemValue;} function DivUlLiList(){ // items属性 this .items = new Array(); // 页面是否加载完毕 // this.isDomReady=false; // 项目文本和项目值的目标文本框 this .textTargetTextbox = null ; this .valueTargetTextbox = null ; // 自动过滤模式:text或value this .EnableAutoFilter = false ; this .autoFilterMode = " text " ; this .selectItem = new function (){ // 注意:此处的this指new function()函数对象 this .itemText = "" ; this .itemValue =- 1 ; }(); // 辅助定位层 this .divAssistant = new function (){ var div = document.createElement( " div " ); div.id = " divAssistant " ; div.style.display = " none " ; div.style.backgroundColor = " #FFFFFF " ; div.style.position = " absolute " ; div.style.border = " black 1px solid " ; document.body.appendChild(div); return div; }(); this .ulBorder = new function (parentObj){ var ul = document.createElement( " ul " ); ul.id = " ulBorder " ; ul.style.width = " 100% " ; ul.style.listStyle = " none " ; ul.style.margin = " 0 " ; ul.style.padding = " 0 " ; parentObj.appendChild(ul); return ul; }( this .divAssistant);} // add方法:向列表中添加项 DivUlLiList.prototype.addItem = function (itemText, itemValue){ try { this .addListItem(itemText,itemValue); this .addListLiNode(itemText,itemValue); } catch (e) { alert(e.message); }} // 功能:向UL中添加Li元素 DivUlLiList.prototype.addListLiNode = function (itemText, itemValue){ try { var that = this ; var liObj = document.createElement( " li " ); // liObj.name="li01"; liObj.style.width = " 100% " ; liObj.innerText = itemText; this .ulBorder.appendChild(liObj); } catch (e) { alert(e.message); }} // 功能:向项目列表中添加ListItem对象 DivUlLiList.prototype.addListItem = function (itemText, itemValue){ try { var itemObj = new ListItem(itemText, itemValue); this .items[ this .items.length] = itemObj; } catch (e) { alert(e.message); }} // 功能:从Json字符串中加载列表项。 // Json字符串必须为一个数组,且每个数组元素都包含itemText, itemValue两个属性. DivUlLiList.prototype.LoadItemFromJsonString = function (itemArrayJsonStr){ try { var itemArr = eval(itemArrayJsonStr); for ( var iNum = 0 ;iNum < itemArr.length;iNum ++ ) { this .addItem(itemArr[iNum].itemText,itemArr[iNum].itemValue); // this.addListItem(itemArr[iNum].itemText,itemArr[iNum].itemValue); // this.addListLiNode(itemArr[iNum].itemText,itemArr[iNum].itemValue); } } catch (e) { alert(e.message); }} // clearItems方法:删除项列表中的所有项 DivUlLiList.prototype.clearItems = function (){ try { this .items.length = 0 ; this .selectItem = new ListItem( "" , - 1 ); } catch (e) { alert(e.message); }}DivUlLiList.prototype.clearLiNodes = function (){ try { var itemLength = this .ulBorder.getElementsByTagName( ' li ' ).length; for ( var i = itemLength - 1 ; i >= 0 ; i -- ) { this .ulBorder.removeChild( this .ulBorder.childNodes[i]); } } catch (e) { alert(e.message); }} // 功能:将下拉列表附加到指定的文本框 DivUlLiList.prototype.BindTargetTxtboxEvent = function (){ try { // 保存当前类的实例 var that = this ; // alert(this.items.length); if (that.textTargetTextbox) { that.textTargetTextbox.onclick = function (){ // 此处不使用this的原因:该函数被调用时,this会被切换到textTargetTextbox对象上去,不再是类的实例 that.SetAsstDivPos(that.textTargetTextbox); } // onkeypress,onkeyup if (that.EnableAutoFilter == true ) { // 模拟AutoComplete功能 that.textTargetTextbox.onkeyup = function (){ that.clearLiNodes(); for ( var iNum = 0 ;iNum < that.items.length;iNum ++ ) { var curItem = that.items[iNum]; // toUpperCase if (that.autoFilterMode.toLowerCase() == " text " ) { if (curItem.itemText.indexOf(that.textTargetTextbox.value) >- 1 ) { that.addListLiNode(curItem.itemText,curItem.itemValue); } } else { if (curItem.itemValue.indexOf(that.textTargetTextbox.value) >- 1 ) { that.addListLiNode(curItem.itemText,curItem.itemValue); } } } } } } } catch (e) { alert(e.message); }} // SetAsstDivPos方法:定位辅助层到附加控件的下方 DivUlLiList.prototype.SetAsstDivPos = function (objAttachTarget){ try { // alert(this.items.length); var topVal = 0 ; var leftVal = 0 ; var elemObj = objAttachTarget; while (elemObj = elemObj.offsetParent){ topVal += elemObj.offsetTop; leftVal += elemObj.offsetLeft; } // alert(this.constructor); this .divAssistant.style.top = topVal + objAttachTarget.offsetHeight + " px " ; this .divAssistant.style.left = leftVal + " px " ; this .divAssistant.style.width = objAttachTarget.offsetWidth; this .divAssistant.style.display = " block " ; } catch (e) { alert(e.message); }}DivUlLiList.prototype.BindItemEvents = function (){ try { var that = this ; var liArr = that.ulBorder.getElementsByTagName( " li " ); for ( var iNum = 0 ;iNum < liArr.length;iNum ++ ) { var liObj = liArr[iNum]; // alert(that.selectItem.itemText); liObj.onclick = new function (){ var curItem = that.items[iNum]; return function (){ that.selectItem = curItem; that.textTargetTextbox.value = curItem.itemText; if (that.valueTargetTextbox) that.valueTargetTextbox.value = curItem.itemValue; that.divAssistant.style.display = " none " ; } }; liObj.onmouseover = function (){ this .style.backgroundColor = " #0000FF " ; }; liObj.onmouseout = function (){ this .style.backgroundColor = " #FFFFFF " ; }; } } catch (e) { alert(e.message); }} // 功能:向服务器提交参数请求数据,服务器必须返回包含itemText和itemValue属性的对象数组的Json字符串 DivUlLiList.prototype.PostXmlHttpRequest = function (xmlHttp,url,postData){ try { var that = this ; xmlHttp.open( ' POST ' , url); xmlHttp.onreadystatechange = function () { if (xmlHttp.readyState == 4 ) { if (xmlHttp.status == 200 ) { that.LoadItemFromJsonString(xmlHttp.responseText); } } }; xmlHttp.setRequestHeader( ' Content-Type ' , ' application/x-www-form-urlencoded;charset=UTF-8 ' ); xmlHttp.send(postData); } catch (e) { alert(e.message); }}
以下是使用例子
DivUlLiListDemo.htm <! 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 > 下拉列表框测试 </ title > < script type ="text/javascript" src ="DivUlLiList.js" ></ script > < script type ="text/javascript" > // var listObj=null; window.onload = function (){ this .listObj = new DivUlLiList(); this .listObj.textTargetTextbox = document.getElementById( " txtObj " ); this .listObj.valueTargetTextbox = document.getElementById( " txt2 " ); this .listObj.EnableAutoFilter = true ; this .listObj.autoFilterMode = " text " ; this .listObj.LoadItemFromJsonString( ' [{"itemText":"A123","itemValue":"a123"},{"itemText":"B234","itemValue":"b234"}] ' ); /* this.listObj.addItem("项目X1","X1"); this.listObj.addItem("项目X2","X2"); this.listObj.addItem("项目1",1); this.listObj.addItem("项目2",2); */ this .listObj.BindTargetTxtboxEvent(); this .listObj.BindItemEvents(); } </ script > </ head > < body > < table > < tr > < td > 姓名 </ td > < td > < input type ="text" id ="txtObj" onclick ="" /> < input type ="text" id ="txt2" onclick ="" /> </ td > </ tr > < tr > < td colspan =2 > < input type ="button" value ="显示" onclick ="alert(listObj.selectItem.itemValue);" /> < input type ="button" value ="清空" onclick ="listObj.clearItems();alert(listObj.items.length);alert(listObj.selectItem.itemValue);" /></ td > </ tr > </ table > </ body > </ html >
本人只是做了简单的测试,也许会有很多的bug,欢迎大家指正。由于本人的javascript水平不是很好,所以有些问题还没想到解决办法,比如如何让本类自动判断dom是否加载完毕,加载完毕后再添加各控件的事件,如何让window.onload事件不被本类占用,及与Asp.net的.ashx文件配合使用等等。因此欢迎大家提供有效的建议,谢谢。
转载于:https://www.cnblogs.com/feima-lxl/archive/2011/07/12/2103553.html
