2009-09-15 76 views
4

我正在使用此代碼來搜索約500個li標籤。用jQuery快速搜索大列表

$(function() { 

    $.expr[":"].containsInCaseSensitive = function(el, i, m){ 
     var search = m[3]; 
     if (!search) return false; 
     return eval("/" + search + "/i").test($(el).text()); 
    }; 

    $('#query').focus().keyup(function(e){ 
     if(this.value.length > 0){ 
      $('ul#abbreviations li').hide(); 
      $('ul#abbreviations li:containsInCaseSensitive(' + this.value + ')').show(); 
     } else { 
      $('ul#abbreviations li').show();  
     } 
     if(e.keyCode == 13) { 
      $(this).val(''); 
      $('ul#abbreviations li').show(); 
     } 
    }); 

}); 

這裏是HTML:

<input type="text" id="query" value=""/> 
<ul id="abbreviations"> 
<li>ABC<span>description</span></li> 
<li>BCA<span>description</span></li> 
<li>ADC<span>description</span></li> 
</ul> 

這個腳本是用這麼多的李標籤很慢。

我該如何加快速度,以及如何在li中搜索槽只有ABC文本,而不是span標籤(不更改html)?

我知道現有的插件,但我需要一個像這樣的小實現。

這裏有興趣的人

var abbrs = {}; 

$('ul#abbreviations li').each(function(i){ 
    abbrs[this.firstChild.nodeValue] = i; 
}); 

$('#query').focus().keyup(function(e){ 
    if(this.value.length >= 2){ 
     $('ul#abbreviations li').hide(); 
     var filterBy = this.value.toUpperCase(); 
     for (var abbr in abbrs) { 
      if (abbr.indexOf(filterBy) !== -1) { 
       var li = abbrs[abbr]; 
       $('ul#abbreviations li:eq('+li+')').show(); 
      } 
     }  
    } else { 
     $('ul#abbreviations li').show();  
    } 
    if(e.keyCode == 13) { 
     $(this).val(''); 
     $('ul#abbreviations li').show(); 
    } 
}); 

回答

7

緩存中的所有物品放入一個對象第一:

var abbrs = {}; 

$("ul#abbreviations li").each(function (i) { 
    abbrs[this.firstChild.nodeValue] = this; 
}); 

然後尋找你的對象中鍵入的文本:

var li = abbrs[this.value.toUpperCase()]; 
// show li, hide others 

更新:部分匹配,你必須遍歷通過收集:

var filterBy = this.value.toUpperCase(); 

for (var abbr in abbrs) { 
    if (abbr.indexOf(filterBy) !== -1) { 
     var li = abbrs[abbr]; 
     // show li 
    } 
} 
+1

+1正確的想法,但只有當li內部的值是唯一的時,這才能正確工作。你也正在做一個完全匹配。 – 2009-09-15 21:39:04

+0

啊...部分匹配...嗯,我想添加所有首字母縮略詞子串的排列將是一個醜陋的選擇。 – 2009-09-15 22:18:59

+0

代碼中的一些錯誤,應該是:var abbrs = {}; \t $( 'UL#縮寫立')每個(函數(I){ \t \t abbrs [this.firstChild.nodeValue] = I; \t})。 - 我怎樣才能進行部分比賽? – 2009-09-16 18:33:48

2

對於初學者完成的代碼,我會用new RegExp代替eval,看看是否有更好的性能。

我假設你是動態填充li標籤。有沒有一種方法可以直接從這個列表中搜索數據結構,而不是搜索DOM對象?如果我的假設不正確,您是否可以在開始時循環查看列表並構建一組字符串,然後可以搜索這些字符串?

編輯:這裏是你如何構建字符串列表

var listTerms = []; 

$("ul#abbreviations li").each(function (li) { 
    listTerms.push({text : li.firstChild.nodeValue, elem : li}); 
}); 

這裏是你如何尋找(簡單的循環,沒有什麼花哨)

var exp = new RegExp(text, "i"); 
for(var i=0; i<listTerms.length; i++) { 
    if (exp.match(listTerms[i].text)) { 
     $(listTerms[i].elem).hide(); 
    } 
} 
+0

我沒有動態填充鋰標籤。內容只是簡單的HTML,僅此而已。你能舉出最後一個問題的例子嗎? – 2009-09-15 18:45:53

0

我不是一個JavaScript編碼器或熟悉jquery,但是前一段時間我有一個類似的問題,那就是針對項目規範提案的js eye-candy目錄樹。

正則表達式顯然是您的瓶頸。 JavaScript沒有高效的數組處理函數,而不是正則表達式的全部開銷?在文檔加載時解析HTML時,<li>標記是否已經解析到DOM數組中?在這些<li>節點上遍歷DOM樹,將它們複製到數組中,然後在生成的數組上使用'find_value'類型的函數來查找值應該很簡單。

+0

是不是,的確, – 2009-09-15 18:17:08