zl程序教程

您现在的位置是:首页 >  后端

当前栏目

JS仿百度搜索自动提示框匹配查询功能

JS搜索百度自动 查询 功能 匹配 提示框
2023-06-13 09:15:12 时间

1.添加动态加载css文件不需要引入csscss全部在JS动态生成。
2.不需要额外的标签只需要一个input输入框并且默认指定一个class类名为"inputElem"当然也可以自己配置参数还需要一个当前父级容器增加一个默认类名parentCls(也可以自己配置),因为输入框匹配值后需要一个隐藏域所以需要隐藏域增加一个class"hiddenCls"当然也支持自己配置参数。

如下代码:

复制代码代码如下:


<divclass="parentCls">
       <divstyle="width:200px;height:26px;border:1pxsolid#ccc;">
           <inputtype="text"class="inputElem"style="width:200px;height:26px;line-height:26px;"/>
       </div>
       <inputtype="hidden"class="hiddenCls"/>
   </div>


   <divclass="parentCls">
       <divstyle="width:200px;height:26px;border:1pxsolid#ccc;">
           <inputtype="text"class="inputElem"style="width:200px;height:26px;line-height:26px;"/>
       </div>
       <inputtype="hidden"class="hiddenCls"/>
   </div>

3.支持页面上有多个输入框。

4.支持鼠标点击和键盘上移和下移键操作类似于百度输入框。
页面上所有的标签都是动态的生成的,不需要额外的标签。如上面的只需要input标签其他的div标签不依赖只需要父级元素增加class"parentCls"(当然可以自己配置类名),
及要传给后台开发人员的隐藏域输入框增加一个class"hiddenCls"当然也可以自动配置参数。

我的模糊查询匹配的需求是这样的:
1.每keyup时候点击或者键盘上移下移操作输入框填充用户名/工号隐藏域填充工号发请求服务器返回数据渲染出来。当然隐藏域填充工号值是form表单提交时候后台要拿到提交过来的工号所以需要这么一个隐藏域。
2.当用户直接在输入框输入值时候并没有键盘上移下移或者点击下拉框某一项时候当鼠标失去焦点时候(blur)当前输入框值为空隐藏域值为空,这样做的目的是为了防止上次form提交过后的数据仍然保存在隐藏域里面当用户重新输入的时候用户也并没有操作键盘上下移操作或者点击操作再点击提交按钮时(失去焦点),那么值为空隐藏域值为空这样防止搜索出来不是用户输入的那个东东。
3.当用户点击某一项时候或者上移下移时候输入框动态的生成值且输入框值现在不能重新输入只有当点击输入框x的时候才可以重新输入。
4.已经遗留输入框可以多选的接口目前还未完善输入框多选的操作。
5.禁止ctrl+v或者右键粘贴操作。

下面HTML代码如下:

复制代码代码如下:


<divclass="parentCls">
       <divstyle="width:200px;height:26px;border:1pxsolid#ccc;">
           <inputtype="text"class="inputElem"style="width:200px;height:26px;line-height:26px;"/>
       </div>
       <inputtype="hidden"class="hiddenCls"/>
   </div>


   <divclass="parentCls">
       <divstyle="width:200px;height:26px;border:1pxsolid#ccc;">
           <inputtype="text"class="inputElem"style="width:200px;height:26px;line-height:26px;"/>
       </div>
       <inputtype="hidden"class="hiddenCls"/>
   </div>

   <inputtype="button"value="提交"/>

JS代码如下:

复制代码代码如下:
/**
 *JS模糊查询
 *@authortugenhua
 *@date2013-11-19
 *@param1.当前的inputaddtargetCls
 *2.隐藏域里面统一增加同类名叫hiddenCls
 *3.在各个父级元素上添加类名parentCls
 */

 functionAutoComplete(options){
    this.config={
       targetCls         :".inputElem",         //输入框目标元素
       parentCls         :".parentCls",         //父级类
       hiddenCls         :".hiddenCls",         //隐藏域input
       searchForm        :".jqtransformdone",    //form表单
       hoverBg           :"hoverBg",            //鼠标移上去的背景
       outBg             :"outBg",              //鼠标移下拉的背景
       isSelectHide      :true,                //点击下拉框是否隐藏
       url               :"",                   //url接口
       height            :0,                    //默认为0不设置的话那么高度自适应
       manySelect        :false,                //输入框是否多选默认false单选
       renderHTMLCallback:null,                 //keyup时渲染数据后的回调函数
       callback          :null,                 //点击某一项提供回调
       closedCallback    :null                  //点击输入框某一项x按钮时回调函数
    };

    this.cache={
       currentIndex       :-1,
       oldIndex           :-1,
       inputArrs          :[]                //多选时候输入框值放到数组里面去
    };
    this.init(options);
 }

 AutoComplete.prototype={

   constructor:AutoComplete,
   init:function(options){

       this.config=$.extend(this.config,options||{});
       varself=this,
           _config=self.config,
           _cache=self.cache;

        //鼠标点击输入框时候
         $(_config.targetCls).each(function(index,item){

             /*
              * 禁止ctrl+v和黏贴事件
              */
             $(item).unbind("paste");
             $(item).bind("paste",function(e){
                 e.preventDefault();
                 vartarget=e.target,
                     targetParent=$(target).closest(_config.parentCls);
                 $(this).val("");
                 $(_config.hiddenCls,targetParent)&&$(_config.hiddenCls,targetParent).val("");
             });

             $(item).keyup(function(e){
                 _cache.inputArrs=[];
                 vartargetVal=$.trim($(this).val()),
                     keyCode=e.keyCode,
                     elemHeight=$(this).outerHeight(),
                     elemWidth=$(this).outerWidth();

                 //如果输入框值为空的话那么隐藏域的value清空掉
                 if(targetVal==""){
                      varcurParents=$(this).closest(_config.parentCls);
                      $(_config.hiddenCls,curParents).val("");
                 }
                 vartargetParent=$(this).parent();
                 $(targetParent).css({"position":"relative"});

                 if($(".auto-tips",targetParent).length==0){
                     //初始化时候动态创建下拉框容器
                    $(targetParent).append($("<divclass="auto-tipshidden"></div>"));
                    $(".auto-tips",targetParent).css({"position":"absolute","top":elemHeight,"left":"0px","z-index":999,"width":elemWidth,"border":"1pxsolid#ccc"});
                 }

                 
                 varcurIndex=self._keyCode(keyCode);
                 if(curIndex>-1){
                         self._keyUpAndDown(targetVal,e,targetParent);
                   }else{
                        if(targetVal!=""){
                           self._doPostAction(targetVal,targetParent);
                        }

                   }
             });

             //失去焦点时如果没有点击或者上下移时候直接输入那么当前输入框值情况隐藏域值情况
             $(item).blur(function(e){
                 vartarget=e.target,
                     targetParent=$(target).closest(_config.parentCls);
                 if($(this).attr("up")||$(this).attr("down")){
                    return;
                 }else{
                    $(this).val("");
                    $(_config.hiddenCls,targetParent).val("");
                 }
             });

         });

         //阻止form表单默认enter键提交
         $(_config.searchForm).each(function(index,item){
              $(item).keydown(function(e){
                   varkeyCode=e.keyCode;
                   if(keyCode==13){
                       returnfalse;
                   }
              });
         });

         //点击文档
         $(document).click(function(e){
            e.stopPropagation();
            vartarget=e.target,
                tagParent=$(target).parent(),
                attr=$(target,tagParent).closest(".auto-tips");

            vartagCls=_config.targetCls.replace(/^\./,"");

            if(attr.length>0||$(target,tagParent).hasClass(tagCls)){
               return;
            }else{
               $(".auto-tips").each(function(index,item){
                   !$(item,tagParent).hasClass("hidden")&&$(item,tagParent).addClass("hidden");
               });

            }
         });

         varstylesheet=".auto-tips{margin:01px;list-style:none;height:auto!important;padding:0px;position:absolute;border:1pxsolid#ccc;top:27px;left:0;z-index:999;width:100%;background:#fff!important;}"+
                          ".auto-tipsp{overflow:hidden;margin:1px0;padding:5px5px;border-bottom:1pxsolid#e7e7e7;color:#666;text-decoration:none;line-height:23px;white-space:nowrap;cursor:pointer;zoom:1;}"+
                          ".auto-tipspimg{vertical-align:middle;float:left;}"+
                          ".create-input{line-height:26px,padding-left:3px;}"+
                          ".create-inputspan{margin-top:1px;height:24px;float:left;}"+
                          ".create-inputspani,.auto-tipsspana{font-style:normal;float:left;cursor:default;}"+
                          ".create-inputspana{padding:08px03px;cursor:pointer;}"+
                          ".auto-tipsp.hoverBg{background-color:#669cb6;color:#fff;cursor:pointer;}"+
                          ".hidden{display:none;}";

         this._addStyleSheet(stylesheet);

   },
   /**
    *键盘上下键操作
    */
   _keyUpAndDown:function(targetVal,e,targetParent){
       varself=this,
           _cache=self.cache,
           _config=self.config;

       //如果请求成功后返回了数据(根据元素的长度来判断)执行以下操作
       if($(".auto-tipsp",targetParent)&&$(".auto-tipsp",targetParent).length>0){

           varplen=$(".auto-tipsp",targetParent).length,
               keyCode=e.keyCode;
               _cache.oldIndex=_cache.currentIndex;

           //上移操作
           if(keyCode==38){
               if(_cache.currentIndex==-1){
                   _cache.currentIndex=plen-1;
               }else{
                   _cache.currentIndex=_cache.currentIndex-1;
                   if(_cache.currentIndex<0){
                       _cache.currentIndex=plen-1;
                   }
               }
               if(_cache.currentIndex!==-1){

                   !$(".auto-tips.p-index"+_cache.currentIndex,targetParent).hasClass(_config.hoverBg)&&
                   $(".auto-tips.p-index"+_cache.currentIndex,targetParent).addClass(_config.hoverBg).siblings().removeClass(_config.hoverBg);
                   varcurAttr=$(".auto-tips.p-index"+_cache.currentIndex,targetParent).attr("data-html"),
                       embId=$(".auto-tips.p-index"+_cache.currentIndex,targetParent).attr("embId");

                   //判断是否是多选操作多选操作暂留接口
                   if(_config.manySelect){
                       _cache.inputArrs.push(curAttr);
                       _cache.inputArrs=self._unique(_cache.inputArrs);
                       self._manySelect(targetParent);
                   }else{
                       $(_config.targetCls,targetParent).val(curAttr);
                       //上移操作增加一个属性当失去焦点时候判断有没有这个属性
                       if(!$(_config.targetCls,targetParent).attr("up")){
                           $(_config.targetCls,targetParent).attr("up","true");
                       }
                       

                       varpCls=$(_config.targetCls,targetParent).closest(_config.parentCls);
                       $(_config.hiddenCls,pCls).val(embId);

                       self._createDiv(targetParent,curAttr);
                       self._closed(targetParent);
                       //hover
                       self._hover(targetParent);
                   }

               }

           }elseif(keyCode==40){//下移操作
               if(_cache.currentIndex==plen-1){
                   _cache.currentIndex=0;
               }else{
                   _cache.currentIndex++;
                   if(_cache.currentIndex>plen-1){
                       _cache.currentIndex=0;
                   }
               }
               if(_cache.currentIndex!==-1){

                   !$(".auto-tips.p-index"+_cache.currentIndex,targetParent).hasClass(_config.hoverBg)&&
                   $(".auto-tips.p-index"+_cache.currentIndex,targetParent).addClass(_config.hoverBg).siblings().removeClass(_config.hoverBg);
                   varcurAttr=$(".auto-tips.p-index"+_cache.currentIndex,targetParent).attr("data-html"),
                       embId=$(".auto-tips.p-index"+_cache.currentIndex,targetParent).attr("embId");

                   
                   //判断是否是多选操作多选操作暂留接口
                   if(_config.manySelect){
                       _cache.inputArrs.push(curAttr);
                       _cache.inputArrs=self._unique(_cache.inputArrs);
                       self._manySelect(targetParent);
                   }else{
                       $(_config.targetCls,targetParent).val(curAttr);

                       //下移操作增加一个属性当失去焦点时候判断有没有这个属性
                       if(!$(_config.targetCls,targetParent).attr("down")){
                           $(_config.targetCls,targetParent).attr("down","true");
                       }

                       varpCls=$(_config.targetCls,targetParent).closest(_config.parentCls);
                       $(_config.hiddenCls,pCls).val(embId);
                       self._createDiv(targetParent,curAttr);
                       self._closed(targetParent);
                       //hover
                       self._hover(targetParent);
                   }

               }
           }elseif(keyCode==13){//回车操作
               varcurVal=$(".auto-tips.p-index"+_cache.oldIndex,targetParent).attr("data-html");
               $(_config.targetCls,targetParent).val(curVal);
               if(_config.isSelectHide){
                   !$(".auto-tips",targetParent).hasClass("hidden")&&$(".auto-tips",targetParent).addClass("hidden");
               }

               _cache.currentIndex=-1;
               _cache.oldIndex=-1;

           }
       }
   },
   //键码判断
   _keyCode:function(code){
       vararrs=["17","18","38","40","37","39","33","34","35","46","36","13","45","44","145","19","20","9"];
       for(vari=0,ilen=arrs.length;i<ilen;i++){
           if(code==arrs[i]){
               returni;
           }
       }
       return-1;
   },
   _doPostAction:function(targetVal,targetParent){

       var self=this,
            _cache=self.cache,
            _config=self.config,
            url=_config.url;

       //假如返回的数据如下:
       varresults=[{lastName:"tugenhua",emplId:"E0987",image:""},{lastName:"tugenhua",emplId:"E0988",image:""},{lastName:"tugenhua",emplId:"E0989",image:""}];
       self._renderHTML(results,targetParent);
       self._executeClick(results,targetParent);
      /**$.get(url+"?keyword="+targetVal+"&timestamp="+newDate().getTime(),function(data){
           varret=$.parseJSON(data.content),
               results=ret.results;
           if(results.length>0){
               self._renderHTML(results,targetParent);
               self._executeClick(results,targetParent);
           }else{
               !$(".auto-tips",targetParent).hasClass("hidden")&&$(".auto-tips",targetParent).addClass("hidden");
               $(".auto-tips",targetParent).html("");

           }
       });**/

   },
   _renderHTML:function(ret,targetParent){
       varself=this,
           _config=self.config,
           _cache=self.cache,
           html="";

       for(vari=0,ilen=ret.length;i<ilen;i+=1){
           html+="<p data-html=""+ret[i].lastName+"("+ret[i].emplId+")"embId=""+ret[i].emplId+""class="p-index"+i+"">"+
                      "<imgsrc=""+ret[i].image+""style="margin-right:5px;"height="25"width="25"title=""alt="">"+
                      "<span>"+ret[i].lastName+"("+ret[i].emplId+")</span>"+
                   "</p>";
       }
       //渲染值到下拉框里面去
       $(".auto-tips",targetParent).html(html);
        $(".auto-tips",targetParent).hasClass("hidden")&&$(".auto-tips",targetParent).removeClass("hidden");
       $(".auto-tipsp:last",targetParent).css({"border-bottom":"none"});

       _config.renderHTMLCallback&&$.isFunction(_config.renderHTMLCallback)&&_config.renderHTMLCallback();

       //出现滚动条计算p的长度*一项p的高度是否大于设置的高度如是的话出现滚动条反之
       varplen=$(".auto-tipsp",targetParent).length,
           pheight=$(".auto-tipsp",targetParent).height();

       if(_config.height>0){
           if(plen*pheight>_config.height){
               $(".auto-tips",targetParent).css({"height":_config.height,"overflow":"auto"});
           }else{
               $(".auto-tips",targetParent).css({"height":"auto","overflow":"auto"});
           }
       }
   },
   /**
     *当数据相同的时点击对应的项时返回数据
     */
   _executeClick:function(ret,targetParent){
       varself=this,
           _config=self.config,
           _cache=self.cache;
        $(".auto-tipsp",targetParent).unbind("click");
        $(".auto-tipsp",targetParent).bind("click",function(e){
             vardataAttr=$(this).attr("data-html"),
                 embId=$(this).attr("embId");

             //判断是否多选
             if(_config.manySelect){
                 _cache.inputArrs.push(dataAttr);
                 _cache.inputArrs=self._unique(_cache.inputArrs);
                 self._manySelect(targetParent);
             }else{
                $(_config.targetCls,targetParent).val(dataAttr);
                varparentCls=$(_config.targetCls,targetParent).closest(_config.parentCls),
                    hiddenCls=$(_config.hiddenCls,parentCls);
                $(hiddenCls).val(embId);
                self._createDiv(targetParent,dataAttr);

                //hover
                self._hover(targetParent);

                !$(_config.targetCls,targetParent).hasClass("hidden")&&$(_config.targetCls,targetParent).addClass("hidden");
             }
             self._closed(targetParent);
             if(_config.isSelectHide){
                 !$(".auto-tips",targetParent).hasClass("hidden")&&$(".auto-tips",targetParent).addClass("hidden");
             }
             _config.callback&&$.isFunction(_config.callback)&&_config.callback();
        });

        //鼠标移上效果
        $(".auto-tipsp",targetParent).hover(function(e){
            !$(this,targetParent).hasClass(_config.hoverBg)&&
            $(this,targetParent).addClass(_config.hoverBg).siblings().removeClass(_config.hoverBg);
        });
   },
   _hover:function(targetParent){
       $(".create-inputspan",targetParent).hover(function(){
           $(this).css({"background":"#ccc","padding-left":"0px"});
       },function(){
            $(this).css({"background":""});
       });
   },
   //动态的创建div标签遮住input输入框
   _createDiv:function(targetParent,dataAttr){
        varself=this,
            _config=self.config;
        variscreate=$(".create-input",targetParent);

        //确保只创建一次div
        if(iscreate.length>0){
           $(".create-input",targetParent).remove();
        }
        $(targetParent).prepend($("<divclass="create-input"><span><i></i></span></div>"));
        $(".create-inputspani",targetParent).html(dataAttr);
        $(_config.targetCls,targetParent).val(dataAttr);
        $(".create-inputspan",targetParent).append("<aclass="alink">X</a>");
        $(".alink",targetParent).css({"float":"left","background":"none"});
   },
   //X关闭事件
   _closed:function(targetParent){
        varself=this,
            _config=self.config;
        /*
         *点击X关闭按钮
         *判断当前输入框有没有up和down属性有的话删除掉否则什么都不做
         */
         $(".alink",targetParent).click(function(){
            $(".create-input",targetParent)&&$(".create-input",targetParent).remove();
            $(_config.targetCls,targetParent)&&$(_config.targetCls,targetParent).hasClass("hidden")&&
            $(_config.targetCls,targetParent).removeClass("hidden");
            $(_config.targetCls,targetParent).val("");
            //清空隐藏域的值
            varcurParent=$(_config.targetCls,targetParent).closest(_config.parentCls);
            $(_config.hiddenCls,curParent).val("");

            vartargetInput=$(_config.targetCls,targetParent);
            if($(targetInput).attr("up")||$(targetInput).attr("down")){
                $(targetInput).attr("up")&&$(targetInput).removeAttr("up");
                $(targetInput).attr("down")&&$(targetInput).removeAttr("down");
            }
            _config.closedCallback&&$.isFunction(_config.closedCallback)&&_config.closedCallback();
         });
   },
   /*
    *数组去重复
    */
   _unique:function(arrs){
       varobj={},
           newArrs=[];
       for(vari=0,ilen=arrs.length;i<ilen;i++){
           if(obj[arrs[i]]!=1){
               newArrs.push(arrs[i]);
               obj[arrs[i]]=1;
           }
       }
       returnnewArrs;
   },
   /*
    *输入框多选操作
    */
   _manySelect:function(targetParent){
       varself=this,
           _config=self.config,
           _cache=self.cache;
       if(_cache.inputArrs.length>0){
           $(_config.targetCls,targetParent).val(_cache.inputArrs.join(","));
       }
   },
   /*
    *判断是否是string
    */
    _isString:function(str){
       returnObject.prototype.toString.apply(str)==="[objectString]";
    },
   /*
    *JS动态添加css样式
    */
   _addStyleSheet:function(refWin,cssText,id){

       varself=this;
       if(self._isString(refWin)){
           id=cssText;
           cssText=refWin;
           refWin=window;
       }
       refWin=$(refWin);
       vardoc=document;
       varelem;

       if(id&&(id=id.replace("#",""))){
           elem=$("#"+id,doc);
       }

       //仅添加一次,不重复添加
       if(elem){
           return;
       }
      //elem=$("<style></style>");不能这样创建IE8有bug
       elem= document.createElement("style");
       //先添加到DOM树中,再给cssText赋值,否则csshack会失效
       $("head",doc).append(elem);

       if(elem.styleSheet){//IE
           elem.styleSheet.cssText=cssText;
       }else{//W3C
           elem.appendChild(doc.createTextNode(cssText));
       }
   },
   /*
    *销毁操作释放内存
    */
   destory:function(){
       varself=this,
           _config=self.config,
           _cache=self.cache;
       _cache.ret =[];
       _cache.currentIndex=0;
       _cache.oldIndex=0;
       _cache.inputArrs=[];
       _config.targetCls=null;
   }
 };
 //初始化
 $(function(){
   varauto=newAutoComplete({
      //url:"/rocky/commonservice/user/find.json"
   });
 });