精华帖 (0) :: 良好帖 (13) :: 新手帖 (0) :: 隐藏帖 (1)
|
|
---|---|
作者 | 正文 |
发表时间:2009-11-17
最后修改:2009-11-18
公司产品的一个新功能中涉及到一个过滤器:通过关键字快速的对结果集进行过滤,获得比较少的结果,方便用户选择。在网上找了找,有很多jQuery的插件,要么就是auto complete, 要么就是没有高亮的quick search,都不是很适合我们的场景,于是就自己实现了一个。用起来倒是还过得去,呵呵。
效果图: 对一个List进行过滤(假设List很长,隐藏掉其他无关的项,例子里是美国的50个州,只搜索有"na"字符串的):
将搜索框中的字符收集起来,作为关键字,当搜索框中的内容发生变化时(keyup事件 ),做一次过滤,将匹配的内容高亮起来(如果有上一次的内容,需要做一个清空处理,比如第一次键入的是a,第二次键入的是al,则在al键入之后要将之前高亮的a恢复正常)。
主要用到了javascript的正则表达式,还有就是jQuery的强大的选择器,下边看看具体代码(demo附后下载): /** * this is the do-filter function, used to filter the contents * * @params contents contents is the container of all items which * need to filter, it's a jQuery object. * * @params keyword keyword is a string, used to be the condition * of the filter * * @params options options is a JSON object, may contains: * { * keep : true or false to detemine whether keep the container or not, * reopts : regular expression options, may be "g", "i", or "gi" * } * */ function doFilter(contents, keyword, options){ var filterOptions = jQuery.extend({ keep : false, reopts : "gi", highlight : "#caff70" }, options); if(!filterOptions.keep){contents.hide();} contents.each(function(){ var text = $(this).text(); var pattern = new RegExp(keyword, filterOptions.reopts); if(pattern.test(text)){ var item = text.replace(pattern, function(t){ return "<span style=\"background:"+filterOptions.highlight+"\">"+t+"</span>"; }); $(this).html(item).show(); }else{//clear search result of last $(this).find("span").each(function(){ $(this).replaceWith($(this).text()); }) } }); }
主要的选项可以定制,如过滤的规则(正则表达式的选项,全局? 忽略大小写?),高亮色彩的配置,以及是否保留源数据集的可视性。比如,List这种控件,一般是较长的时候进行一下搜索过滤,不需要保持源数据集,而table这种控件,则一般需要保持控件的结构,需要保持源数据集。
用法如下: var sb = $("#searchBox").val("").focus(); var resultSet = $("div#contentPanel div.item");//used for restore sb.keyup(function(){ var str = $(this).val(); doFilter(resultSet, str); }); 首先,将用作填写关键字的input获取到,然后取得数据集的list,包装成jQuery对象,将doFilter绑定到input的keyup事件上即可。
好了,大概也说明白了,自己也加深一下记忆,这一向在实现一套基于web的控件,基本的模型已经差不多了,过两天整理整理分享一下,呵呵。
按照bluemeteor的建议,将highlight参数改成更为通用的css class,用户同时可以将字体信息等传入作为highlight。总体效果如前文中的截图。代码更新如下: function doFilter(contents, keyword, options){ var filterOptions = jQuery.extend({ keep : false, reopts : "gi", highlight : "highlight" }, options); if(!filterOptions.keep){contents.hide();} contents.each(function(){ var text = $(this).text(); var pattern = new RegExp(keyword, filterOptions.reopts); if(pattern.test(text)){ var item = text.replace(pattern, function(t){ return "<span class=\""+filterOptions.highlight+"\">"+t+"</span>"; }); $(this).html(item).show(); }else{//clear search result of last $(this).find("span."+filterOptions.highlight).each(function(){ $(this).replaceWith($(this).text()); }) } }); } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-11-18
看着不错,以前做过个类似的东西,IE好像有backspace的bug(keyup事件无效),不过例子中这个没有问题,也没看见有对IE的特殊处理,^_^?
|
|
返回顶楼 | |
发表时间:2009-11-18
有小建议,说出来讨论一下.XD
高亮的部分是否可以通过class来控制? return "<span class='filterHighLight'>"+t+"</span>"; 这样做可以,第一,通过外部的样式表来定义默认颜色,同时可以扩展,不仅控制背景,还可以很方便得扩展为控制字体。第二,将$(this).find("span").each替换成$(this).find(".filterHighLight").each,这样可以获得更大的应用性,现在这种方式如果元素本身在filter之前就包含span元素的话就会出现问题了 |
|
返回顶楼 | |
发表时间:2009-11-18
bluemeteor 写道 有小建议,说出来讨论一下.XD
高亮的部分是否可以通过class来控制? return "<span class='filterHighLight'>"+t+"</span>"; 这样做可以,第一,通过外部的样式表来定义默认颜色,同时可以扩展,不仅控制背景,还可以很方便得扩展为控制字体。第二,将$(this).find("span").each替换成$(this).find(".filterHighLight").each,这样可以获得更大的应用性,现在这种方式如果元素本身在filter之前就包含span元素的话就会出现问题了 呵呵,这两点都提的非常好。关于第一点,我开始也写的是用css的class做Options,后来觉得用的时候有的人可能不习惯使用class,就写成color了,我觉得class更标准一些,下来改一下。第二点非常之正确,按照你说的这种方式可以消除潜在的bug. 谢谢了! |
|
返回顶楼 | |
发表时间:2009-11-18
代码根据bluemeteor兄的建议做了一点修改,可以下载JFilter2.zip做测试,再次感谢bluemeteor,也希望有更多的意见,呵呵。
|
|
返回顶楼 | |
发表时间:2009-11-20
呃 lz做的不错呢 呵呵 前天我正在看lucene的高亮功能了 感觉不喜欢
|
|
返回顶楼 | |
发表时间:2009-11-22
我怎么感觉很卡,性能有问题
|
|
返回顶楼 | |
发表时间:2009-11-22
个人觉得javascript只是ria过渡时期的选择。想这么简单个FILTER,才50个州,都有严重的性能问题。
|
|
返回顶楼 | |
发表时间:2009-11-23
admyefei 写道 我怎么感觉很卡,性能有问题
我用这个JFilter在FF和IE下都测了下(100条数据),没有感觉卡啊,你用的是什么浏览器?不过如果输入速度很快的话,好像是有些卡哦。 |
|
返回顶楼 | |
发表时间:2009-11-23
个人水平有限,js、jquery仅限于会用,不过东东很好,收藏了!但是代码没看太懂。不知道怎么才能搞懂呢?
|
|
返回顶楼 | |