建议不要用XML,慢,最好自己构造数据结构,比如: function CNode(){ var Chindren=new Object() this.addChild=addChild; this.getChild=getChild; function addChild(CurrentLetter,lastletter){ if (typeof(Chindren[CurrentLetter])=="undefined"){ Chindren[CurrentLetter]=new Array() } Chindren[CurrentLetter].push(lastletter) } function getChild(CurrentLetter){ return Chindren[CurrentLetter] } } 这个代码没有验证,随手写的,提供一种思路而已.当输入第n个字母时,就从树根搜索到第n层(会很快),再将其下所有Children(包括所有子孙)遍历(稍微麻烦一点)就可以得到一个词汇列表. 用类似的Node来构造一棵树,效率比XML将会有数量级的提升.
我做过一个 动态取数据那个function还没写 到时候你自己动态创建一个script tag,就可以动态更新数据了 希望可以对你有用 ================== cmb.js ==================var cmb // text input keydown function txtOnFocus(){ if(!cmb) cmb = new cmbList(); cmb.oldTypedValue=""; cmb.initData(); cmb.autoFill = true; } function txtOnKeyDown(){ var evt = window.event; cmb.keyDown(evt); } function txtOnKeyUp(){ var evt = window.event; cmb.keyUp(evt); }cmbList.prototype.keyDown=function(evt){ this.oldTypedValue = this.target.value; } cmbList.prototype.keyUp=function (evt){ this.keyDownCount +=1; if(this.keyDownCount >1) this.autoFill = true; var code = evt.keyCode; window.status=code; if(code==27) this.hide(); else if(code==13) { var a=this.target; var b=this.cmb; if(this.isShow) { if(b.selectedIndex <1 ) var cc=1; // open a new form here else a.value = b.options[b.selectedIndex].text; this.hide(); } } else if(code==38) this.upArrow(); //up arrow else if(code==40) this.downArrow(); // down arrow else if(code==37) this.leftArrow(); else if(code==39) this.rightArrow(); else if(code==8) this.backSpaceDown(); else if(code==46) this.deleteDown(); else if(code==36) this.deleteDown(); //home else if(code==35) this.deleteDown(); //end else if(code==33) this.deleteDown(); //pageup else this.setSelect(); evt.cancelBubble=true; } // the cmb was clickedfunction selClick(){ var a = cmb.cmb; var idx =a.selectedIndex; if(idx < 1) cmb.target.value =''; else cmb.target.value = a.options[idx].text; cmb.hide(); } function init(){ if(document.readyState=="complete") cmb = new cmbList(); cmb.setField("txtVendorName","txtVendorId");}function showHideCmb(txt,hidden){ if(cmb.isShow) cmb.hide(); else { cmb.initData(); cmb.setField(txt,hidden); cmb.position(); cmb.resize(); cmb.show(); } } function cmbList() { this.div = document.all["divList"]; this.cmb = document.all["cmbList"]; this.keyHistory = "111"; this.isShow = false; this.oldTypedValue =""; this.autoFill = true; this.keyDownCount =0; } cmbList.prototype.txtOnKeyPress=function (){ var s=event.srcElement; } cmbList.prototype.backSpaceDown=function (){ this.keyDownCount =0; this.autoFill = false; } cmbList.prototype.setField = function(txt,hidden){ this.target = document.getElementById(txt); // text input this.hidden = document.getElementById(hidden); // hidden id this.target.onkeydown = txtOnKeyDown; this.target.onkeyup = txtOnKeyUp; }// make the text's value same as listbox cmbList.prototype.synData=function(){ var a=this.target; var h=this.hidden; var b=this.cmb; var idx=b.selectedIndex; if(idx <1) return; a.value =b.options[idx].text; h.value = b.options[idx].value; } cmbList.prototype.downArrow=function() { var a=this.cmb; var idx=a.selectedIndex; if(idx<0) { a.selectedIndex=0;return 0; } else if(idx==a.length-1) return 0; else a.selectedIndex +=1; this.synData(); } cmbList.prototype.leftArrow=function(){ this.autoFill = false; this.keyDownCount = 1; } cmbList.prototype.deleteDown=function(){ this.autoFill = false; this.keyDownCount = 1; } cmbList.prototype.rightArrow=function(){ this.autoFill = false; this.keyDownCount = 1; } cmbList.prototype.upArrow=function(){ var a=this.cmb; var idx=a.selectedIndex; if(idx < 1) a.selectedIndex=0; else a.selectedIndex -=1; this.synData(); }//will init all the data in this function // now only put some test datacmbList.prototype.initData = function(refress){ if(refress || !this.finishInitData) { var a=this.cmb; var o=new Option; o.text =" < add new value > "; o.value =0; a.options[0] = o; var o=new Option; o.text ="bbbtest"; o.value =1; a.options[1] = o; var o=new Option; o.text ="test"; o.value =2; a.options[2] = o; var o=new Option; o.text ="tttest"; o.value =3; a.options[3] = o; var o=new Option; o.text ="ttrtest"; o.value =4; a.options[4] = o; this.finishInitData= true; } }// position the div cmbList.prototype.position = function(){ var pos = new Object(); getOffsetPosition(this.target,pos); this.div.style.left = pos.left; this.div.style.top = pos.top+23; }// make the item which match the textbox selected cmbList.prototype.setSelect=function (){ var a = this.cmb; var len,i; var txt=this.target; var str = txt.value; var find = false; for(i=1;i<a.length;i++) { var b = a.options[i].text; if(a.length <= b.length) { if(str.length>0 && str.toLowerCase()== b.substr(0,str.length).toLowerCase()) { a.selectedIndex = i; find = true; i=1000; } } } if(a.selectedIndex > 0 && find && this.autoFill) { txt.value = a.options[a.selectedIndex].text; var txtR = txt.createTextRange(); txtR.moveStart("character",str.length); txtR.select(); }
} cmbList.prototype.show = function(){ this.div.style.visibility = "visible"; this.isShow = true; this.setSelect(); this.target.focus(); } cmbList.prototype.hide = function(){ this.isShow = false; this.div.style.visibility = "hidden"; this.target.focus(); } cmbList.prototype.resize = function(){ var maxsize =10; var a = this.cmb; if(a.length > maxsize) a.size=maxsize; else if(a.length >=3) a.size=a.length; else a.size=2; }function onchange() { var th=event.srcElement; }// clear select list cmbList.prototype.clearData = function(){ var s = this.sel; for(var i=s.length-1;i>=0;i--) s.remove(i); } // add item cmbList.prototype.addData=function(v,t){ var o=new Option; o.value= v; o.text =t; this.sel.options[this.sel.length] = o; } function getOffsetPosition (node, result) { var node2 = node; var top = node.offsetTop; var width = node.offsetWidth; var left = node.offsetLeft; var pagewidth = document.body.clientWidth;
for (node=node.offsetParent; node != null; node=node.offsetParent) { top = node.offsetTop + top; left = node.offsetLeft + left; } result.top=top; result.left=left;
// Decide whether to align to right or left
/*if ((left + styleResult.pixelWidth) <= pagewidth) { // align to right //used temps above because the code did not work when I did math with these variables directly! styleResult.top = top; styleResult.left = left; } else { // Align to right corner styleResult.top = top; styleResult.left = left; }*/ }
你查一下以前的关于动态树的帖子吧。一样的原理.http://dob.tnc.edu.tw/show_page.php?s=454&t=6当然反应速度要看你的的动态程序和数据库了。
告诉老板JBuilder的开发者年薪是多少。
要看数据量。要是数据两小于100k的话,我肯定在网页上生成一大数组来快速查询。可以直接用jsp在网页上生成出来。然后在按键的时候从数组筛选。
要是数据太多,用户的网速又有限的话,就只有用xmlhttp或者xmldom动态从服务器上拿了。服务器端要相应做一个响应程序查数据库(我都用servlet做的,用xml格式发送数据)。
http://www.lostinet.com/public/getwords/getwords.htm原代码:
http://www.lostinet.com/public/getwords.zip
其中
getwords.htm
getwords.jac.asp
是这次做的。其他的文件可以参考
http://www.lostinet.com/public/
下的jac
所以可能有人看不了。
我现在改成Microsoft.XMLHTTP了。。
不过IE死了不要怪我哦
function CNode(){
var Chindren=new Object() this.addChild=addChild;
this.getChild=getChild; function addChild(CurrentLetter,lastletter){
if (typeof(Chindren[CurrentLetter])=="undefined"){
Chindren[CurrentLetter]=new Array()
}
Chindren[CurrentLetter].push(lastletter)
} function getChild(CurrentLetter){
return Chindren[CurrentLetter]
}
}
这个代码没有验证,随手写的,提供一种思路而已.当输入第n个字母时,就从树根搜索到第n层(会很快),再将其下所有Children(包括所有子孙)遍历(稍微麻烦一点)就可以得到一个词汇列表.
用类似的Node来构造一棵树,效率比XML将会有数量级的提升.
到时候你自己动态创建一个script tag,就可以动态更新数据了
希望可以对你有用
==================
cmb.js
==================var cmb
// text input keydown
function txtOnFocus(){
if(!cmb) cmb = new cmbList();
cmb.oldTypedValue="";
cmb.initData();
cmb.autoFill = true;
}
function txtOnKeyDown(){
var evt = window.event;
cmb.keyDown(evt);
}
function txtOnKeyUp(){
var evt = window.event;
cmb.keyUp(evt);
}cmbList.prototype.keyDown=function(evt){
this.oldTypedValue = this.target.value;
}
cmbList.prototype.keyUp=function (evt){
this.keyDownCount +=1;
if(this.keyDownCount >1) this.autoFill = true; var code = evt.keyCode;
window.status=code;
if(code==27) this.hide();
else if(code==13)
{
var a=this.target;
var b=this.cmb;
if(this.isShow)
{
if(b.selectedIndex <1 )
var cc=1; // open a new form here
else
a.value = b.options[b.selectedIndex].text;
this.hide();
}
}
else if(code==38) this.upArrow(); //up arrow
else if(code==40) this.downArrow(); // down arrow
else if(code==37) this.leftArrow();
else if(code==39) this.rightArrow();
else if(code==8) this.backSpaceDown();
else if(code==46) this.deleteDown();
else if(code==36) this.deleteDown(); //home
else if(code==35) this.deleteDown(); //end
else if(code==33) this.deleteDown(); //pageup
else
this.setSelect();
evt.cancelBubble=true;
}
// the cmb was clickedfunction selClick(){
var a = cmb.cmb;
var idx =a.selectedIndex;
if(idx < 1) cmb.target.value ='';
else cmb.target.value = a.options[idx].text;
cmb.hide();
}
function init(){
if(document.readyState=="complete")
cmb = new cmbList();
cmb.setField("txtVendorName","txtVendorId");}function showHideCmb(txt,hidden){
if(cmb.isShow)
cmb.hide();
else
{
cmb.initData();
cmb.setField(txt,hidden);
cmb.position();
cmb.resize();
cmb.show();
}
}
function cmbList()
{ this.div = document.all["divList"];
this.cmb = document.all["cmbList"];
this.keyHistory = "111";
this.isShow = false;
this.oldTypedValue ="";
this.autoFill = true;
this.keyDownCount =0;
}
cmbList.prototype.txtOnKeyPress=function (){
var s=event.srcElement;
}
cmbList.prototype.backSpaceDown=function (){
this.keyDownCount =0;
this.autoFill = false;
}
cmbList.prototype.setField = function(txt,hidden){
this.target = document.getElementById(txt); // text input
this.hidden = document.getElementById(hidden); // hidden id
this.target.onkeydown = txtOnKeyDown;
this.target.onkeyup = txtOnKeyUp;
}// make the text's value same as listbox
cmbList.prototype.synData=function(){
var a=this.target;
var h=this.hidden;
var b=this.cmb;
var idx=b.selectedIndex;
if(idx <1) return;
a.value =b.options[idx].text;
h.value = b.options[idx].value;
}
cmbList.prototype.downArrow=function()
{
var a=this.cmb;
var idx=a.selectedIndex;
if(idx<0)
{
a.selectedIndex=0;return 0;
}
else if(idx==a.length-1) return 0;
else a.selectedIndex +=1;
this.synData();
}
cmbList.prototype.leftArrow=function(){
this.autoFill = false;
this.keyDownCount = 1;
}
cmbList.prototype.deleteDown=function(){
this.autoFill = false;
this.keyDownCount = 1;
}
cmbList.prototype.rightArrow=function(){
this.autoFill = false;
this.keyDownCount = 1;
}
cmbList.prototype.upArrow=function(){
var a=this.cmb;
var idx=a.selectedIndex;
if(idx < 1) a.selectedIndex=0;
else a.selectedIndex -=1;
this.synData();
}//will init all the data in this function
// now only put some test datacmbList.prototype.initData = function(refress){
if(refress || !this.finishInitData)
{
var a=this.cmb;
var o=new Option;
o.text =" < add new value > ";
o.value =0;
a.options[0] = o;
var o=new Option;
o.text ="bbbtest";
o.value =1;
a.options[1] = o;
var o=new Option;
o.text ="test";
o.value =2;
a.options[2] = o;
var o=new Option;
o.text ="tttest";
o.value =3;
a.options[3] = o;
var o=new Option;
o.text ="ttrtest";
o.value =4;
a.options[4] = o; this.finishInitData= true;
}
}// position the div
cmbList.prototype.position = function(){
var pos = new Object();
getOffsetPosition(this.target,pos);
this.div.style.left = pos.left;
this.div.style.top = pos.top+23;
}// make the item which match the textbox selected
cmbList.prototype.setSelect=function (){
var a = this.cmb;
var len,i;
var txt=this.target;
var str = txt.value;
var find = false;
for(i=1;i<a.length;i++)
{
var b = a.options[i].text;
if(a.length <= b.length)
{
if(str.length>0 && str.toLowerCase()== b.substr(0,str.length).toLowerCase())
{
a.selectedIndex = i;
find = true;
i=1000;
}
}
}
if(a.selectedIndex > 0 && find && this.autoFill)
{
txt.value = a.options[a.selectedIndex].text;
var txtR = txt.createTextRange();
txtR.moveStart("character",str.length);
txtR.select();
}
}
cmbList.prototype.show = function(){
this.div.style.visibility = "visible";
this.isShow = true;
this.setSelect();
this.target.focus();
}
cmbList.prototype.hide = function(){
this.isShow = false;
this.div.style.visibility = "hidden";
this.target.focus();
}
cmbList.prototype.resize = function(){
var maxsize =10;
var a = this.cmb;
if(a.length > maxsize) a.size=maxsize;
else if(a.length >=3) a.size=a.length;
else a.size=2;
}function onchange()
{
var th=event.srcElement;
}// clear select list
cmbList.prototype.clearData = function(){
var s = this.sel;
for(var i=s.length-1;i>=0;i--)
s.remove(i);
}
// add item
cmbList.prototype.addData=function(v,t){
var o=new Option;
o.value= v;
o.text =t;
this.sel.options[this.sel.length] = o;
}
function getOffsetPosition (node, result) {
var node2 = node;
var top = node.offsetTop;
var width = node.offsetWidth;
var left = node.offsetLeft;
var pagewidth = document.body.clientWidth;
for (node=node.offsetParent; node != null; node=node.offsetParent) {
top = node.offsetTop + top;
left = node.offsetLeft + left;
}
result.top=top;
result.left=left;
// Decide whether to align to right or left
/*if ((left + styleResult.pixelWidth) <= pagewidth) {
// align to right
//used temps above because the code did not work when I did math with these variables directly!
styleResult.top = top;
styleResult.left = left;
} else {
// Align to right corner
styleResult.top = top;
styleResult.left = left;
}*/
}
http://webfx.eae.net/dhtml/combobox/combo_demo.htmAPI:
http://webfx.eae.net/dhtml/combobox/ComboBox_API.htm