基于jquery实现智能提示控件intellSeach.js

前端之家收集整理的这篇文章主要介绍了基于jquery实现智能提示控件intellSeach.js前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

一、需求

  我们经常会遇到【站内搜索】的需求,为了提高用户体验,我们希望能做到像百度那样的即时智能提示。例如:某公司人事管理系统,想搜索李XX,只要输入“李”,系统自然会提示一些姓李的员工,这样方便用户使用。说白了,就是用户边输入,系统会提示相关的结果;或者,当用户点击搜索框时,就推荐一些内容,如360、百度都会提示今天的主要新闻或搜索量大的内容

  jquery 已经有一个这样的插件了,叫 autocomplete,但我觉得不好用。关于autocomplete的介绍也很多,有兴趣的朋友可以去试试。

  看标题就知道,这里只是分享一个插件,不会讨论后台搜索的相关算法和过程,也就是说,后台返回特定格式的数据,控件负责渲染结果呈现。ok,先看一下效果图:

  

二、参数说明

  控件以json格式作为传输格式。参数比较多,大部分都有默认值(具体看源码),有些可能不常用,保持默认即可。如下:

  url: 请求地址。如:Handler.ashx,后台获取数据的地址

property: 要显示的json对象的属性。如果我们直接返回["tom","tom cat","tom2"] 这样的形式,那么该属性可以不用设置;但有时候我们会返回[{"Name":"tom","ID":"001"},{"Name":"tom cat","ID":"002"},{"Name":"tom2","ID":"003"}] 这样的形式,显示的是Name,那么设置该属性为"Name"即可。至于我们想在点击的时候获得点击的项的ID,通过点击事件即可。

itemNumber: 显示的项数目。

isEmptyRequest: focus时,空白是否发起请求。就像前面说的,如果点击搜索框时(此时没有内容),想要推荐一些内容,设置该属性为true,即会发起请求。

defaultValue: 默认值。通常会是:“请输入关键词...” 这类的提示

width: 下拉列表宽度。

  aligner: 要对齐的元素。

maxHeight: 最大高度。如果设置该高度,超过时就会出现滚动条。

ajax:{   timeout: 超时时间 cache: 是否缓存 },

  event:{    setData: 发送请求前触发。用于设置参数 itemClick: 点击项触发 enterKeydown: 按下enter键触发 beforeRender: 所有项呈现前触发 endRender: 所有项呈现后触发 itemBeforeRender: 项呈现前触发 itemAfterRender: 项呈现后触发 beforeSend: 发送请求前触发。用户设置请求头部参数等,相当于jquery ajax 的 beforeSend。 }

  event 里的方法都会在适当的时候触发,需要注意的是,所有方法都接收一个参数,该参数是一个对象,有4个属性,某些情况如果没有该属性的,则为空。包括如下属性

  jthis: input 的 jQuery 对象。

  jItem: 项的 jQuery 对象。

data: 返回的 json 字符串。如果在前台需要对返回 json 再进行处理,那么可以通过 data 属性获得,处理完成后,需要将 json 字符串 return。

  event: 事件对象,如按下 enter 时的事件对象。

三、例子

  使用例子:

四、总结

  

  如果你还有自己的逻辑需要处理,也支持链式调用,大可以这样写 $("#search").intellSearch({参数...}).focus(function(){你的处理...});

  分享插件希望能帮助到有需要的朋友,主要用于学习。由于是v1.0,可能还有一些bug,有发现的朋友也可以告诉我,我会及时修正。  

附源代码

js代码

403_99@ 0){ jCurItem.click(); }else{ setIntellObj(null); if(_event.enterKeydown){ _event.enterKeydown({"jthis":jthis,"event":e}); } } jthis.blur(); }else if(jItems.length > 0){ if(code === 38){ if(jCurItem.length <= 0){ jCurItem = jItems.last(); jCurItem.addClass("cur"); keyword = jCurItem.text(); }else{ var index = jCurItem.index(); jCurItem.removeClass("cur"); if(index <= 0){ keyword = value; }else{ jCurItem = jItems.eq(index-1); jCurItem.addClass("cur"); keyword = jCurItem.text(); } } jthis.val(keyword); }else{ if(jCurItem.length <= 0){ jCurItem = jItems.first(); jCurItem.addClass("cur"); keyword = jCurItem.text(); }else{ var index = jCurItem.index(); jCurItem.removeClass("cur"); if(index + 1 >= jItems.length){ keyword = value; }else{ jCurItem = jItems.eq(index+1); jCurItem.addClass("cur"); keyword = jCurItem.text(); } } jthis.val(keyword); } } } } /*event handler*/ $.fn.unintell = function(){ remove(); } $(document).unbind({click:window.intellDocumentClick,keydown:window.intellDocumentKeydown}) .bind({click:window.intellDocumentClick,keydown:window.intellDocumentKeydown}); jthis.focus(function(){ _focusCount++; if(_focusCount > 1){ return; } if(window.intellObj.jthis && jthis !== window.intellObj.jthis){ setIntellObj(null); } var keyword = attrValue(); if(keyword === _dftOpts.defaultValue){ keyword = ""; attrValue(keyword); } if(keyword || _dftOpts.isEmptyRequest){ sendRequest(); } }) jthis.blur(function(){ _focusCount = 0; if(!attrValue()){ attrValue(_dftOpts.defaultValue); } }) jthis.keyup(function(e){ if(e.keyCode === 38 || e.keyCode === 40){ return; } var keyword = attrValue(); if(!keyword){ remove(); window.intellObj.value = _value = ""; return; } if(keyword !== _value){ window.intellObj.value = _value = keyword; sendRequest(); } });
return init<a href="/tag/Box/" target="_blank" class="keywords">Box</a>();

/*function*/
function init<a href="/tag/Box/" target="_blank" class="keywords">Box</a>(){
  attrValue(_dftOpts.defaultValue);
  return jthis;
}    
function initIntell(){      
  generate();
  register();
  setIntellObj({jthis:jthis,jResult:jResult});
}
function generate(){
  var offset = _dftOpts.aligner.offset();
  var width = _dftOpts.width ? _dftOpts.width : _dftOpts.aligner.width();
  jResult = $("<ul>",{"class":"intellResult"});
  jResult.width(width).css({"position":"absolute","left":offset.left,"top":offset.top + jthis.outerHeight()});
  $("body").append(jResult);
  if(_dftOpts.maxHeight > 0){
    jResult.height(_dftOpts.maxHeight).css("overflowY","scroll");
  }
}
function remove(){
  if(jResult){
    jResult.remove();
    jResult = null;
  }
}
function register(){
  jResult.on("click","li",function(){
    var jItem = $(this);
    var index = jItem.index();
    var keyword = jItem.text();
    attrValue(keyword);        
    _value = keyword;        
    if(_event.itemClick){
      _event.itemClick({"jthis":jthis,"jItem":jItem,"item":_cache[index]});
    }
  }).on("mouseenter",function(){
    $(this).siblings("li").removeClass("cur").end().addClass("cur");
  }).on("mouseleave",function(){
    $(this).removeClass("cur");
  });
}
function setIntellObj(obj){
  if(!obj){
    if(window.intellObj.jResult){
      window.intellObj.jResult.remove();
    }
    window.intellObj.jthis = null;
    window.intellObj.jResult = null;
  }else{
    window.intellObj.jthis = obj.jthis;
    window.intellObj.jResult = obj.jResult;
  }
}
function sendRequest(){
  var data;
  if(_event.setData){        
    data = _event.setData({"jthis":jthis});
  }
  $.ajax({
    url:_dftOpts.url,data:data,cache:_ajax.cache,timeout:_ajax.timeout,beforeSend:function(xhr){
      if(_event.beforeSend){
        _event.beforeSend(xhr);
      }
    },success:function(data){
      remove();
      showData(data);
    },error:null
  });
}
function showData(data){
  data = $.trim(data) ? $.parseJSON(data) : data;
  if(_event.beforeRender){
    var rs = _event.beforeRender({"jthis":jthis,"data":data});
    if(rs === false){
      return;
    }
    if(rs !== undefined){
      data = rs;
    }
  }
  if(!data){
    return;
  }
  var jItem,jA,jSpan,hasProp,item,text,otherTexts,isRender,index;
  var list = $.isArray(data) ? data : [data];
  var length = list.length;
  length = length > _dftOpts.itemNumber ? _dftOpts.itemNumber : list.length;
  if(length <= 0){
    return;
  }
  initIntell();
  _cache.length = 0;
  hasProp = list[0][_dftOpts.property];
  for(var i=0;i<length;i++){
    item = list[i];
    if(item === null || item === undefined){
      continue;
    }
    text = hasProp ? item[_dftOpts.property] : item;
    text = $.trim(text.toString());
    if(text === ""){
      continue;
    }
    jItem = $("<li>",{"class":"intellResult_item"});
    jA = $("<a>",{"title":text}).appendTo(jItem);
    jSpan = $("<span>").appendTo(jA);
    index = text.toLowerCase().indexOf(_value.toLowerCase());
    otherTexts = splitText(text,_value,index);
    if(otherTexts){
      jSpan.text(text.substr(index,_value.length));
      if(otherTexts.length > 1){
        $("<b>",{"text":otherTexts[0]}).insertBefore(jSpan);
        $("<b>",{"text":otherTexts[1]}).insertAfter(jSpan);
      }else{
        if(index === 0){
          $("<b>",{"text":otherTexts[0]}).insertAfter(jSpan);
        }else{
          $("<b>",{"text":otherTexts[0]}).insertBefore(jSpan);
        }
      }
    }else{
      jSpan.text(text);
    }
    isRender = true;
    if(_event.itemBeforeRender){
      isRender = _event.itemBeforeRender({"jthis":jthis,"item":item});
    }
    if(isRender !== false){
      jResult.append(jItem);
      if(_event.itemAfterRender){
        _event.itemAfterRender({"jthis":jthis,"item":item});
      }
    }
    _cache.push(item);
  }
  if(_event.endRender){
    _event.endRender({"jthis":jthis});
  }
  jResult.show();
}
function attrValue(value){
  if(!value && value != ""){
    return $.trim(jthis.val());
  }
  jthis.val(value);
}
function splitText(text,value,index){
  var tlength = text.length;
  var vlength = value.length;
  if(index === -1){
    return null;
  }
  if(index === 0){
    if(index + vlength >= tlength){
      return null;
    }
    return [text.substr(index + vlength)];
  }
  if(index + vlength >= tlength){
    return [text.substr(0,index)];
  }
  return [text.substr(0,index),text.substr(index + vlength)];
}

}
})(window,jQuery);

样式

以上就是本文的全部内容,希望对大家的学习有所帮助。

猜你在找的jQuery相关文章