jQuery Autocomplete自动完成插件

  相对于同类插件,他的特色有3点。

  1、可缓存查询结果 (二次查询速度快)

  2、非keyup监听方式 (解决某些系统/情况下无法触发keyxxx事件的问题)

  3、简洁的参数 (好看?)

  插件性能尚好,我的E6500、2G内存,30秒内一共发生了4469次调用,耗时94.65毫秒;百度的是2432次调用,80.24毫秒。

  接近1倍的调用是jQuery中的问题,但具体原因我还没弄明白,如果那位兄弟知道的还请不吝赐教。

  调用方法

  

复制代码 代码如下:

  jQuery("#kw").suggest({

  url:siteConfig.suggestionUrl,

  params:{

  kw:function(){return jQuery("#kw").val()},

  n:10

  }

  });

  参数url:baseUrl,例如http://www.target.com/search.php

  参数params:url的后缀列表,范例中拼合的url为:http://www.target.com/search.php?kw=xxx&n=10&callback=?(默认加入callback)

  参数delay:输入间隔时间,主要是为了降低负载,数值越大,负载越低,查询速度越慢。

  参数cache:是否实用缓存,默认为true,例如当搜索“test”时,程序会将对应的查询结果缓存,当第二次搜索test时直接从缓存中读取。

  参数formId:必须填写,form表单的id

  参数callback:是否使用jsonp以便处理跨域问题。

  核心代码:

  suggest.js

  

复制代码 代码如下:

  (function($){

  $.tools = $.tools || {version: '1.0'};

  $.tools.suggest = {};

  $.tools.suggest.defaults = {

  url : null,

  params : null,

  delay : 100,

  cache : true,

  formId : '#search_form',

  focus:null,

  callback : true

  }

  $.tools.suggest.borderKey = {

  UP: 38,

  DOWN: 40,

  TAB: 9,

  ESC: 27,

  ENTER:13

  }

  $.fn.suggest=function(options,fn){

  var options,key = $.tools.suggest.borderKey;

  if($.isFunction(options)){

  fn=options;

  options = $.extend({}, $.tools.suggest.defaults, key);

  }else{

  options = $.extend({}, $.tools.suggest.defaults, key, options);

  }

  return this.each(function(){

  var

  self = $(this),

  url = options.url,

  params = options.params,

  searchUrl = null,

  searchtimer = 0,

  delay = options.delay,

  cache = options.cache,

  callback = options.callback,

  formobj = $(options.formId),

  focus = options.focus,

  rebox = $('<ul/>').attr("id","suggest"),

  htmlLi = null,

  litop = null,

  lileft = null,

  liwth = null,

  tip = false,

  val = null,

  rlen = null,

  UP = options.UP,

  DOWN = options.DOWN,

  TAB = options.TAB,

  ESC = options.ESC,

  ENTER = options.ENTER,

  index = -1,

  choseKey = null,

  backval = null,

  hidden = false,

  locksuggest = false

  //init

  if(focus){

  self.focus();

  searchtimer = setInterval(getKey, delay);

  }

  self.bind("focus",function(){

  searchtimer = setInterval(getKey, delay);

  // 触发焦点时初始化backval的值

  backval = (backval=$.trim(self.val()))==''?null:backval;

  })

  .bind("blur",function(){

  clearInterval(searchtimer);

  searchtimer = 0;

  hideResult();

  })

  .bind("keydown",function(e){

  // 少于10项不使用switch

  if(e.keyCode == UP){

  clearInterval(searchtimer);

  searchtimer = 0;

  if($('#suggest').css('display') == 'none'){

  reSet();

  return false;

  }

  index--;

  if(index<0){

  index=Math.abs(rlen)-1;

  }

  changeSelect(index);

  e.preventDefault();

  return false;

  }else if(e.keyCode == DOWN){

  clearInterval(searchtimer);

  searchtimer = 0;

  if($('#suggest').css('display') == 'none'){

  reSet();

  return false;

  }

  index++;

  if(index>=rlen){

  index=0;

  }

  changeSelect(index);

  e.preventDefault();

  return false;

  }else if(e.keyCode == TAB){

  clearInterval(searchtimer);

  searchtimer = 0;

  hideResult();

  }else if(e.keyCode == ESC){

  clearInterval(searchtimer);

  searchtimer = 0;

  hideResult();

  return false;

  }else if(e.keyCode == ENTER){

  clearInterval(searchtimer);

  searchtimer = 0;

  }else if(searchtimer == 0){

  searchtimer = setInterval(getKey, delay);

  }

  });

  // 获取关键词

  function getKey(){

  val = $.trim(self.val());

  // 关键词不为空且关键词不重复

  if(!!val && val!=backval){

  backval = val;

  // 如不需要缓存结果,设cache为false

  if(cache && !!$.tools.suggest[val]){

  index = -1;

  rlen = $.tools.suggest[val][1];

  appendSuggest($.tools.suggest[val][0]);

  }else{

  searchurl = url+'?'+$.param(params);

  getResult(searchurl,function(htmltemp,htmllen){

  index = -1;

  rlen = htmllen;

  appendSuggest(htmltemp);

  });

  }

  }

  // 关键词为空

  if(!!!val && !hidden){

  hideResult();

  }

  }

  // 获取提示数据

  function getResult(searchurl,fn){

  if(callback){searchurl = searchurl+'&callback=?';}

  $.getJSON(searchurl,function(data){

  var htmltemp = '',

  htmllen = 0,

  inputWord = self.val()

  $.each(data.list,function(i,n){

  if(n.word != inputWord){

  htmltemp += '<li>'+n.word+'</li>';

  htmllen++;

  }

  });

  if(cache && !!!$.tools.suggest[val]){$.tools.suggest[val]=[htmltemp,htmllen];}

  fn.call(document,htmltemp,htmllen)

  });

  }

  // 插入提示数据

  function appendSuggest(result){

  locksuggest = hidden = false;

  if(!!result){

  if(!tip){

  litop = self.offset().top+self.outerHeight()-1;

  lileft = self.offset().left;

  liwth = self.outerWidth()-2;

  rebox.css({'position':'absolute','top':litop,'left':lileft,'width':liwth}).html(result).appendTo('body').show();

  tip = true;

  }else{

  rebox.html(result).show();

  }

  rebox.find('li').bind('mouseover',function(){

  // 锁定提示层,保证不因冒泡关闭提示层

  locksuggest = true;

  index = $(this).index();

  changeSelect(index,false);

  })

  .bind('click',function(){

  changeSelect(index);

  searchSubmit();

  });

  rebox.bind('mouseout',function(){

  locksuggest = false;

  })

  }else{

  // 如果检索结果为空,清空提示层

  rebox.hide();

  }

  }

  function changeSelect(index,v){

  v=v==false?false:true;

  var obj = rebox.find('li').eq(index);

  rebox.find('li.mo').removeClass('mo');

  obj.addClass("mo");

  if(v){

  choseKey = backval = obj.html();

  self.val(choseKey);

  }

  }

  function reSet(){

  if(!!self.val()){

  index = -1;

  $('#suggest').css('display','block');

  rebox.find('li.mo').removeClass('mo');

  // 根据html结构重新计算提示结果长度

  rlen = rebox.find('li').size();

  }

  }

  function hideResult(){

  if(!locksuggest){

  choseKey = backval = null;

  hidden = true;

  rebox.hide();

  }

  }

  function searchSubmit(){

  self.val(choseKey);

  hideResult();

  clearInterval(searchtimer);

  formobj.submit();

  }

  });

  }

  })(jQuery);

  代码打包下载