JQuery appendTo非常慢!

时间:2009-07-01 14:54:45

标签: javascript jquery client

我有一个html表,我根据每个表行的自定义属性值的CSV列表重新排序。我使用以下函数来执行此操作:

for (var i = 0; i < arrCSV.length; i++)
{
  $('#' + tableId)
      .find('[fname = ' + arrCSV[i] + ']')
      .eq(0)
      .parents('tr')
      .eq(0)
      .appendTo('#' + tableId);
}

表结构是:

<table>
<tr>
 <td fname='f1'>something here</td>
</tr>
<tr>
 <td fname='f2'>something here</td>
</tr>
</table>

CSV可能是这样的“f2,f1”

我发现这是非常非常慢的功能。我们非常感谢您对优化它的任何帮助。

修改: 基于http://www.learningjquery.com/2009/03/43439-reasons-to-use-append-correctly上的文章,通过使用html连接字符串仅调用一次,可以实现性能的最大提升。有人可以帮助我使用这种技术解决我的问题吗?我不知道如何在for循环中获取HTML并将其追加一次。

4 个答案:

答案 0 :(得分:1)

我建议尽可能少地找到元素。使用感兴趣的属性值作为关键字将所有匹配的行存储到“哈希”中。浏览你的CSV,从哈希中选择相应的行,将其推入一个数组,最后使用之前找到的jQuery对象将数组元素附加到表中。

var table = $('#' + tableId);
var rowHash = {};
table.find('[fname]').each( function() {
    rowHash[$(this).attr('fname')] = $(this).closest('tr');
});
var rows = [];
for (var i = 0; i < arrCSV.length; ++i)
{
    var row = rowHash[arrCSV[i]];
    if (row) {
       rows.push(row);
    }
}
$(rows).appendTo(table);

编辑:这似乎比我以前的代码略有改进,我将每行追加到表中。我在一个有1000行的表上测试过,似乎需要大约1秒才能对需要完全反转的表进行排序。

答案 1 :(得分:1)

如果你只想追加一次html(就像那个learningjquery.com文章一样),请试试以下内容:

$(document).ready(
function()
{
   var arrCSV = ['f2', 'f1'];
   var tableId = 'mainTable';
   var newTable = [];
   for (var i = 0; i < arrCSV.length; i++)
   {
      var row = $('#' + tableId)
                .find('[fname = ' + arrCSV[i] + ']')
                .eq(0)
                .parents('tr')
                .eq(0);

      newTable.push(row.html());
   }                    

   $('#' + tableId).html(newTable.join(''));
};
});

实时版:http://jsbin.com/uwipo 代码:http://jsbin.com/uwipo/edit

虽然我个人觉得你应该首先对你的代码进行分析,然后看看它是否附加了缓慢或“找到”方法调用。我想,对于一个巨大的表,使用'find method'来查找自定义属性可能会很慢。但同样,任何猜测都没有意义,可以对代码进行分析并找出答案。

如果'find'方法很慢,是否可以在td上使用id属性而不是给出自定义属性。

e.g。

<table>
<tr>
   <td id='f1'>something here</td>
</tr>
<tr>
   <td id='f2'>something here</td>
</tr>
</table>

然后,找到父行的代码可以简单如下:

  ('#' + arrCsv[i]).parent('tr')

编辑:正如tvanfosson所指出的,此代码假定arrCSV包含所有行的属性。最终表将只包含arrCSV中存在的那些行。此外,此代码不会复制原始表中的'thead','tfoot'部分,尽管编写代码应该很容易。

答案 2 :(得分:0)

您可能需要重新考虑您的算法。

在不改变算法的情况下,稍作优化就是:

var $table = $("#" + tableId);

for (var i = 0; i < arrCSV.length; i++)
{
  $('[fname = ' + arrCSV[i] + ']:first',$table).closest('tr').appendTo($table);
}

答案 3 :(得分:0)

等一下......

$('#' + tableId)

获取#myTable

.find('[fname = ' + arrCSV[i] + ']')

查找属性为fname等于i

的任何内容
.eq(0)

给我上一个表达式的第一项

.parents('tr')

找到TR类型的父母

.eq(0)

给我上一个表达式中的第一个

.appendTo('#' + tableId);

将TR添加到#myTable

好。现在我已经把它分解了 - 你只复制一个表行吗?如果是这样,.append()不是你的问题,你选择的选择器是。为了进一步加剧我的困惑,唯一具有fname属性的标签是你的TR,所以为什么你要去他们的父母()并寻找第一个TR?您基本上要求将TR标记放在TR标记内 - 但这不是您的标记示例所示。