一、需求
我们经常会遇到【站内搜索】的需求,为了提高用户体验,我们希望能做到像百度那样的即时智能提示。例如:某公司人事管理系统,想搜索李xx,只要输入“李”,系统自然会提示一些姓李的员工,这样方便用户使用。说白了,就是用户边输入,系统会提示相关的结果;或者,当用户点击搜索框时,就推荐一些内容,如360、百度都会提示今天的主要新闻或搜索量大的内容。
jquery 已经有一个这样的插件了,叫 autocomplete, 但我觉得不好用。关于autocomplete的介绍也很多,有兴趣的朋友可以去试试。
看标题就知道,这里只是分享一个插件,不会讨论后台搜索的相关算法和过程,也就是说,后台返回特定格式的数据,控件负责渲染结果呈现。ok,先看一下效果图:
样式与控件无关,只需要一个 input text 就可以了。
二、参数说明
控件以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({ url:handler.ashx, property:name, itemnumber:5, isemptyrequest:false, defaultvalue:请输入关键字..., width:$(#search).width() + 2, maxheight:-1, event:{ itemclick:function(obj){ alert(obj.item.id); }, enterkeydown:function(obj){ if(obj.item){ alert(有当前项); }else{ alert(没有当前项); } } } });
四、总结
如果你还有自己的逻辑需要处理,也支持链式调用,大可以这样写 $(#search).intellsearch({参数...}).focus(function(){你的处理...});
分享该插件希望能帮助到有需要的朋友,主要用于学习。由于是v1.0,可能还有一些bug,有发现的朋友也可以告诉我,我会及时修正。
附源代码
js代码
/*搜索智能提示 v1.0 date:2015.09.08 */;(function(w,$){ $.fn.intellsearch = function(options){ var jthis = this; var _dftopts = { url:,//请求地址或数组 property:,//要显示的json对象的属性 itemnumber:5,//显示的条数 isemptyrequest:false,//focus空白是否发起请求 defaultvalue:,//默认值 width:0,//列表宽度 aligner:jthis,//要对齐的元素 maxheight:-1,//最大高度 ajax:{ timeout:3000,//超时时间 cache:true//是否缓存 }, event:{ /*参数说明:parameter:{jthis:jq input,jitem:jq item,data:json result,event:event}*/ setdata:null,//设置参数 itemclick:null,//点击项触发 enterkeydown:null,//按下enter键触发 beforerender:null,//所有项呈现前触发 endrender:null,//所有项呈现后触发 itembeforerender:null,//项呈现前触发 itemafterrender:null,//项呈现后触发 beforesend:null//发送请求前触发 } }; $.extend(_dftopts,options); if(!_dftopts.url){ throw error(url不能为空!); } var jresult; var _value = ; var _ajax = _dftopts.ajax; var _event = _dftopts.event; var _cache = []; var _focuscount = 0;//防止focus触发多次(sogou) /*on window*/ window.intellobj = window.intellobj || {}; /*for global event*/ window.intelldocumentclick = window.intelldocumentclick || function(e){ if(!window.intellobj.jthis){ return; } if(e.target !== window.intellobj.jthis[0]){ setintellobj(null); } } window.intelldocumentkeydown = window.intelldocumentkeydown || function(e){ var jthis = window.intellobj.jthis; if(!jthis){ return; } var code = e.keycode; var value = window.intellobj.value; var jresult,jcuritem,keyword; if(code === 13 || code === 38 || code === 40){ jresult = window.intellobj.jresult; jitems = jresult.find(li); jcuritem = jresult.find(li.cur); if(code === 13){ if(jcuritem.length > 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){ 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,li,function(){ $(this).siblings(li).removeclass(cur).end().addclass(cur); }).on(mouseleave,li,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 = 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);
样式
.intellresult{margin:0;padding:0;background:#fff;border:1px solid #b6b6b6;clear:both;z-index:999;display:none;}.intellresult li{margin:0;padding:0;padding:5px 15px;height:20px;line-height:20px;overflow:hidden;text-overflow:ellipsis;cursor:pointer;white-space:nowrap;}.intellresult li.cur{background:#e5e0e0;}
以上就是本文的全部内容,希望对大家的学习有所帮助。
