完成输入框输入的自动匹配功能。
参考:http://www.yisoutong.cn/html/?11112.html
这里增加了和输入拼音相对应的中文匹配。
如果能进一步完善,多谢指教。核心JS代码如下,DEMO见附件。
/** * 输入框的自动匹配核心控制类 * @param $fixDom 存放用于匹配的值的DIV对象 */ function InputAutoFix($aConfig){ var aConfig=$aConfig; var _msgEn=[]; //预先用于匹配的值,匹配值的拼音描述 var _msgCh=[]; //预先用于匹配的值,匹配值的中文描述 var _sb=null; //和输入值匹配的值 var _domCh=aConfig.fixDom; if(_domCh==null || typeof(_domCh)=="undefined"){ return; } var _canFix=false; //能否匹配 var _instance=null; var _key=null; var _inputDom=aConfig.inputDom; //输入框对象 var _index=0; //匹配容器中匹配值的索引 var _isNotOut=false; //匹配值索引是否超出匹配值的长度 var _currentValue=null; //当前输入框中的值 _domCh.style.visibility="hidden"; _domCh.style.position="absolute"; _domCh.style.zIndex="999"; _domCh.style.overflowY="auto"; _domCh.style.overflowX="hidden"; _domCh.style.height="50"; //初始化为50 this.beginHandleAuto=beginHandleAuto; this.directionKey=directionKey; // 针对匹配结果进行键盘操作的事件定义 this.doMouseover=doMouseover; //匹配值的onmouseover事件时的样式 this.doMouseout=doMouseout; //匹配值的onmouseout事件时的样式 this.doOnclick=doOnclick; //匹配值的onclick事件定义 this.item=item; //存储预先准备匹配的值 this.append=append; //把匹配的值加载到匹配值的容器中 this.display=display; //找到匹配值后显示存放匹配值的容器 this.setInstance=setInstance; //设置实例 function setInstance($instanceName,$aConfigInstance){ _instance=$instanceName; aConfig.instance=$aConfigInstance; } /** * 开始匹配 * @param $inputValue * @param $event */ function beginHandleAuto($inputValue){ _currentValue=$inputValue; if(_currentValue==""){ if(_domCh.style.visibility=="visible"){ _domCh.style.visibility="hidden"; } return; } var isEn=false; var regDirty=/^(\/|\?|\,)|\\/; //非法字符输入 if(regDirty.test(_currentValue)){ return; } var regChar=/^([A-Za-z])+$/i; //英文输入的匹配 var reg=new RegExp("^"+_currentValue+"","i"); //从开始位置进行匹配,忽略大小写 _canFix=false; // _isNotOut=true; _sb=[]; _domCh.innerHTML=""; //当前输入的是英文 if(regChar.test(_currentValue)){ isEn=true; } //对输入的值进行匹配 for(var i=0;i<_msgCh.length;i++){ //当前输入的是英文 if(isEn){ if(_msgEn.length>0){ if(reg.test(_msgEn[i])){ if(_msgCh[i]!=null){ append(_msgCh[i]);//显示和英文对应的中文 _canFix=true; } } } }else{ //输入中文进行匹配 if(_msgCh[i]!=null){ if(reg.test(_msgCh[i])){ append(_msgCh[i]); _canFix=true; } } } } //匹配后显示匹配容器 try{ display(); }catch(e){ alert("不能正常显示匹配容器:"+e.description); return; } //对匹配容器中的匹配值进行特殊的样式处理 if(_canFix){ if(event.keyCode==13 || event.keyCode==40 || event.keyCode==38){ //enter,down,up directionKey(); }else{ _index=0; _domCh.childNodes[_index].className="mouseover"; _isNotOut=true; } } }; /** * 把和输入的值匹配的匹配值加载到匹配容器中并显示 * @param $value 和输入的值相匹配的匹配容器中的匹配值 */ function append($value){ if($value==null){ return; } var fixValue=$value; _sb.push(fixValue); var divDom=document.createElement("DIV"); //对匹配的值进行鼠标事件的绑定,主要是改变样式 divDom.οnmοuseοver=function(){doMouseover(this);} divDom.οnmοuseοut=function(){doMouseout(this)}; divDom.οnclick=function(){doOnclick(fixValue)}; //如果匹配,对输入框中的值进行加粗处理 var reg=new RegExp("("+_currentValue+")","i"); divDom.style.lineHeight="140%"; divDom.className="mouseout"; if(_currentValue){ divDom.innerHTML=$value.replace(reg,"<strong>$1</strong>"); //对匹配的字符进行加粗处理 } divDom.style.fontFamily="宋体"; _domCh.appendChild(divDom); }; /** * 针对匹配结果进行键盘操作的事件定义 : * 1、在匹配结果中向上移动光标 * 2、在匹配结果中向下移动光标 * 3、对合适的匹配结果进行enter的操作 * 注意: 各个匹配结果的索引的变化 */ function directionKey(){ var key=event.keyCode; var len=_domCh.childNodes.length; if(_index>len-1 || _index<0){ _isNotOut=false; } if(key==40 && _isNotOut){ //光标向下移动 _domCh.childNodes[_index].className="mouseout"; if(_index>=len-1){ _index=0; }else{ _index++; } try{ _domCh.childNodes[_index].className="mouseover"; }catch(e){ alert("key=40"+e.description); } } if(key==38 && _isNotOut){ //光标向上移动 _domCh.childNodes[_index].className="mouseout"; if(_index<=0){ _index=len-1; }else{ _index--; } try{ _domCh.childNodes[_index].className="mouseover"; }catch(e){ alert("key=38"+e.description); } } if(key==13){ //enter if(_domCh.childNodes[_index] && _domCh.style.visibility=="visible"){ _inputDom.value=_sb[_index]; _domCh.style.visibility="hidden"; } } if(!_isNotOut){ //重新初始化索引 _index=0; _domCh.childNodes[0].className="mouseover"; _isNotOut=true; } }; /** * 对匹配值所在的dom进行onmousever的事件样式处理 * @param $obj 匹配值所在的dom */ function doMouseover($obj){ var dom=$obj; if(_domCh.childNodes.length==0){ //return; }else{ _domCh.childNodes[_index].className="mouseout"; } _index=0; if(dom.tagName=="DIV"){ dom.className="mouseover"; }else{ dom.parentElement.className="mouseover"; } }; /** * 匹配值的onmouseout事件时的样式 * @param $obj */ function doMouseout($obj){ var dom=$obj; if(dom.tagName=="DIV"){ dom.className="mouseout"; }else{ dom.parentElement.className="mouseout"; } }; /** * 对匹配值的进行选择的onclick事件 * @param $msg 匹配容器中和输入值相匹配的值 */ function doOnclick($msg){ var v=$msg; if(_inputDom==null){ return; } _inputDom.value=v; //选定匹配值后隐藏显示匹配值的容器 _domCh.style.visibility="hidden"; }; //隐藏下拉面板 this.hideSel=hideSel; function hideSel(){ if(_domCh.style.visibility=="visible"){ _domCh.style.visibility="hidden"; } } /** * 存储用于匹配的值 * 如果值有多个,用,分隔 * @param $msg 用于匹配的值 * @param $tag 值类型的标记 */ function item($msg,$tag){ var items=$msg; if(items.indexOf(",")!=0){ var arrMsg=items.split(","); for(var i=0;i<arrMsg.length;i++){ if(arrMsg[i]!=null){ if("ch"==$tag){ //中文 _msgCh.push(arrMsg[i]); }else{ //和中文对应的拼音 _msgEn.push(arrMsg[i]); } } } }else{ if("ch"==$tag){ _msgCh.push(items); }else{ _msgEn.push(items); } } //@note: 因为要中文及其拼音对应,所以这里不再做排序处理 // _msgCh.sort(); // _msgEn.sort(); }; /** * 显示用于匹配的匹配容器 */ function display(){ if(_canFix && _currentValue!=null){ var dom=_inputDom; var x=0; var y=0; while(dom!=null){ x+=dom["offsetLeft"]; y+=dom['offsetTop']; dom=dom.offsetParent; } _domCh.style.left=x; _domCh.style.height=_msgCh.length+80; _domCh.style.width=_inputDom.offsetWidth; _domCh.style.top=y+22; _domCh.style.visibility="visible"; }else { _domCh.style.visibility="hidden"; } }; } /** * 自动匹配所用的dom对象配置 * @param $inputDom 匹配用的输入框对象 * @param $fixDomEn 存放中文匹配值div对象 * @param $fixDomCh 存放和中文相对应的英文匹配值的div对象 */ function AutoDomConfig($inputDom,$fixDom){ this.instance=null; //AutoDomConfig对象实例 this.css="autoFix.css"; this.inputDom=$inputDom; this.fixDom=$fixDom; } function AutoFix(){ this.init=init; var autoFix=null; var inputDom=null; var dom=null; var config=null; var msgCh=null; var msgEn=null; /** * 执行初始化操作 * @param $dom 输入框对象 * @param $fixDom 存放匹配值的对象 * @param $fixDomCh 存放匹配值的对象,一般是英文对应的中文 */ function init($dom,$fixDom,$msgCh,$msgEn){ dom=$fixDom; inputDom=$dom; msgCh=$msgCh; msgEn=$msgEn; config=new AutoDomConfig(inputDom,dom); var instance=inputDom.getAttribute("wc.instance"); autoFix=new InputAutoFix(config); autoFix.setInstance(instance,config); eval("window."+instance+"=autoFix"); __loadCss(config.css); if(msgCh!=null && msgCh.length>0){ autoFix.item(msgCh,"ch"); }if(msgEn!=null && msgEn.length>0){ autoFix.item(msgEn,"en"); } }; this.doHide=doHide; function doHide(){ if(autoFix==null){ return; } autoFix.hideSel(); } /** * 开始匹配 * @param $currentValue */ this.beginRender=beginRender; function beginRender($currentValue){ var currentValue=$currentValue; autoFix.beginHandleAuto(currentValue); } //加载CSS文件 function __loadCss($css) { var node = document.createElement("LINK"); node.rel = "Stylesheet"; node.type = "text/css"; node.href = $css; document.all.tags("HEAD")[0].appendChild(node); } } var auFix=new AutoFix();