Posted in Javascript onJuly 17, 2010
相对于同类插件,他的特色有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);
代码打包下载
jQuery Autocomplete自动完成插件
声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。
Reply on: @reply_date@
@reply_contents@