2013-02-16 45 views
1

我有一個包含字符串列表的數百行的html表。我也有一個輸入框,可以在表格中插入新的行。每一行中的第二個TD元素始終是一個div內的字符串,所以在表中的行可能是這樣的:使用jquery通過很多元素搜索時減慢

<tr> 
    <td><span class="ui-icon ui-icon-arrowthick-2-n-s"></span> 
    </td> 
    <td class="a_string" style="width:200px;"> 
     <div style="word-wrap:break-word;">hello world</div> 
    </td> 
    ... 
</tr> 

我想插入新行基於從一個字符串列表,在此表用戶,如果一個字符串已經在表中,它將被忽略並且不被插入。當用戶字符串列表非常長且表中的行數很長時,我用來檢查重複項的方法效率太低,因此對於此任務來說效率太低:

function check_rows(item) { //called on each item in input list 
    var tf = false; 
    $('#mytable tbody').children().each(function (i) { 
     //loop through each tr 

     if ($('#mytable tbody').children().eq(i).children().eq(1).hasClass('a_string')) { 
      //if the row is a string to compare (second td element has the class 'a_string') 

      if (item == $('#mytable tbody').children().eq(i).children().eq(1).children().eq(0).html()) { 
       //find the string within the div within second td in row "i" (current indexed row) 
       //compare the strings and if it is found in the table break out of the loop 

       tf = true; 
       return false; 
      } 
     } 
    }); 
    //if the item is not found in any of the rows false will be returned 
    return tf; 
} 

該函數做它應該做的事(檢查重複的字符串),它只是太慢了。我試圖插入沒有這個功能的列表,它幾乎是瞬間的,所以問題在這裏。

有關如何改善此功能的任何建議將不勝感激!

+1

$('#mytable tbody')'被調用的次數太多。你有沒有嘗試存儲參考?你能跟蹤數組中的項目列表,而不是從DOM中檢查項目嗎? – nhahtdh 2013-02-16 01:36:41

+0

@nhahtdh是的,我可以,我不認爲這會產生任何效果。我一直不關心jquery的執行速度,因爲直到現在它還沒有實現。將存儲對tbody的引用並將表中的項目數組保存在一起會提高我的性能? – 2013-02-16 01:43:51

+1

有太多的DOM遍歷,這有點​​更好 - > [** FIDDLE **](http://jsfiddle.net/tsu5c/),但不是很多? – adeneo 2013-02-16 01:46:11

回答

1

你可以試試beolw代碼。您不必在每個內部使用$('#mytable tbody'),而是使用this

嘗試將元素分配給一個變量,它會創建一個引用會快得多。

function check_rows(item) { //called on each item in input list 
    var tf = false; 
    $('#mytable tbody').children().each(function (i) { 
     //loop through each tr 

     var tr = $(this).eq(i).children();  
     if (tr.eq(1).hasClass('a_string')) { 
      //if the row is a string to compare (second td element has the class 'a_string') 

      if (item == tr.eq(1).eq(0).html()) { 
       //find the string within the div within second td in row "i" (current indexed row) 
       //compare the strings and if it is found in the table break out of the loop 

       tf = true; 
       return false; 
      } 
     } 
    }); 
    //if the item is not found in any of the rows false will be returned 
    return tf; 
} 
+0

謝謝,我會試試這個。 – 2013-02-18 17:27:42

+0

我最終做了這樣的事情,謝謝! – 2013-02-18 20:59:03

0

如果您知道您將要對相同材質進行一堆DOM搜索,那麼您可能希望將相關數據的副本轉換爲JavaScript數據結構,該數據結構比搜索要快得多每次遍歷DOM。

如果您正在檢查字符串的完全匹配,您甚至可以使用JavaScript對象的索引功能爲您提供一個非常快速的是/否的答案,以確定您的數據結構中是否存在確切的字符串。這應該比通過DOM的線性搜索快幾個數量級。

0

我會用選擇這樣

function check_rows(item) { //called on each item in input list 
    var tf = false, 
     mytbody = $('#mytable tbody'), 
     secondCell; 
    $('tr', mytbody).each(function (i) { 
     //loop through each tr 
     secondCell = $('td', this).eq(1); 
     if (secondCell.hasClass('a_string')) { 
      //if the row is a string to compare (second td element has the class 'a_string') 

      if (item == $('div:first', secondCell).html()) { 
       //find the string within the div within second td in row "i" (current indexed row) 
       //compare the strings and if it is found in the table break out of the loop 

       tf = true; 
       return false; 
      } 
     } 
    }); 
    //if the item is not found in any of the rows false will be returned 
    return tf; 
} 
+0

你能向我解釋一下選擇器'$('div:first',secondCell)'是如何工作的嗎? – 2013-02-18 17:28:55

+0

它似乎不喜歡'secondCell'的定義 – 2013-02-18 20:01:38

+0

這是一個子選擇器,試試這個然後'secondCell = $('td:eq(1)',this)' – kidwon 2013-02-19 09:12:37