公司產品的一個新功能中涉及到一個過濾器:通過關鍵字快速的對結果集進行過濾,獲得比較少的結果,方便用戶選擇。在網上找了找,有很多jQuery的插件,要麼就是auto complete, 要麼就是沒有高亮的quick search,都不是很適合我們的場景,於是就自己實現了一個。用起來倒是還過得去,呵呵。
效果圖:
對一個List進行過濾(假設List很長,隱藏掉其他無關的項,例子裏是美國的50個州,只搜索有"na"字符串的):
對一個table進行過濾(table的其他列不隱藏,只是高亮搜索到的):
當然,可以將其結合在一起,那樣一個頁面中可以有多個過濾器:
其實,實現起來,代碼量很小,這裏先大概說一下原理:
將搜索框中的字符收集起來,作爲關鍵字,當搜索框中的內容發生變化時(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()); }) } }); }