2013-02-16 49 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