修正因网络延迟而导致的显示错误
增加关键词高亮功能
修正了部分代码
使用固定的回调函数
插件代码:
(function($){ $.tools = $.tools || {version: '1.2'}; $.tools.suggest = {}; $.tools.suggest.defaults = { url : null, params : null, delay : 100, cache : true, formId : '#search_form', focus:null } $.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, 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, timer = null ; /* 初始化 */ if(focus){ self.trigger('focus'); } /* 初始化绑定事件 */ self.bind("focus",function(){ backval = (backval=$.trim(self.val()))==''?null:backval; /* 触发焦点时初始化backval的值 */ getQueue(); }) .bind("blur",function(){ clearQueue(); hideResult(); }) .bind("keydown",function(e){ switch (e.keyCode){ case UP: clearQueue(); if($('#suggest').css('display') == 'none'){ reSet(); return false; } index--; if(index<0){ index=Math.abs(rlen)-1; } changeSelect(index); e.preventDefault(); break; case DOWN: clearQueue(); if($('#suggest').css('display') == 'none'){ reSet(); return false; } index++; if(index>=rlen){ index=0; } changeSelect(index); e.preventDefault(); break; case TAB: clearQueue(); hideResult(); break; case ESC: clearQueue(); hideResult(); e.preventDefault(); break; case ENTER: clearQueue(); break; default: getQueue(); break; } }); // 获取关键词 function getKey(){ val = $.trim(self.val()); if(!!val && val!=backval){ /* 关键词不为空且关键词不重复 */ backval = val; if(cache && !!$.tools.suggest[val]){ /* 如不需要缓存结果,设cache为false */ index = -1; rlen = $.tools.suggest[val][1]; appendSuggest($.tools.suggest[val][0]); }else{ $.tools.suggest[val] = ["",0]; searchurl = url+'?'+$.param(params); getResult(searchurl); } } if(!!!val && !hidden){ hideResult(); /* 如果关键词为空并且层没有隐藏则隐藏提示层 */ } } /* 获取提示数据 */ function getResult(searchurl){ $.ajax({ type: "GET", url: searchurl, cache: true, dataType: "jsonp", jsonpCallback: "$.fn.suggest.suggetCallback" }); } /* 插入提示数据 */ 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(); } } /* JSONP 回调函数 */ $.fn.suggest.suggetCallback = function(tmp){ var data = tmp, htmltemp = '', htmllen = data.total, inputWord = data.kw; if(htmllen > 0){ $.each(data.list,function(i,n){ if(n.word != inputWord){ htmltemp += '<li data-value="'+n.word+'">'+n.word+'</li>'; } }); htmltemp = htmltemp.toLocaleLowerCase(); var regex = eval("/\>"+inputWord+"/g"); htmltemp = htmltemp.replace(regex,"><b>"+inputWord+"</b>"); $.tools.suggest[inputWord]=[htmltemp,htmllen]; } if(self.val() == inputWord){ rlen = htmllen; index = -1; appendSuggest(htmltemp); } } /* 创建队列 */ function getQueue(){ var n = $(document).queue("suggest"); if(n.length < 1){ $(document).queue("suggest",getQueue); getKey(); timer = setTimeout((function(){ $(document).dequeue("suggest"); }),delay); } } /* 清除队列 */ function clearQueue(){ $(document).clearQueue("suggest"); clearTimeout(timer); } /* 变更选项 */ 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.attr("data-value"); self.val(choseKey); } } /* 重置层 */ function reSet(){ if(!!self.val()){ index = -1; $('#suggest').css('display','block'); rebox.find('li.mo').removeClass('mo'); rlen = rebox.find('li').size(); /* 根据html结构重新计算提示结果长度 */ } } /* 隐藏结果层 */ function hideResult(){ if(!locksuggest){ choseKey = backval = null; hidden = true; rebox.hide(); } } /* 提交表单 */ function searchSubmit(){ self.val(choseKey); clearQueue(); hideResult(); formobj.submit(); } }); } })(jQuery);
返回数据格式
$.fn.suggest.suggetCallback({"total":2,"list":[{"id":"8926","word":"ZAMA\u00b7\u54b1\u4eec"},{"id":"44723","word":"ZOBON"}],"kw":"z"})
