我有一个表格,其中有一个切换显示/隐藏符合特定条件的各种行,我使用以下JS来实现我想要的(JSFiddle);
function resetRows() {
var i = 1,
tds;
var start = new Date().getTime();
$('td').removeClass('even odd');
$.each($('tr'), function (key, index) {
// loop through each table row skipping the first row which will be the title
tds = $(this).find($('td'));
if ($(this).is(':visible') && key > 0) {
if (i % 2 === 0) {
tds.addClass('even');
} else {
tds.addClass('odd');
}
// find the .index class and reset it's value
$(this).find($('.index')).html(i);
i++;
}
});
var end = new Date().getTime();
var time = end - start;
console.log('time taken: ' + time);
}
$(function () {
// show/hide failed
$('#showHideFails').on('click', function () {
if ($('.failed').eq(0).is(':visible')) {
$('.failed, .ins').hide();
$('.shTxt').html('Show all');
resetRows();
} else {
$('.failed, .ins').show();
$('.shTxt').html('Hide failed');
resetRows();
}
});
});
我的问题是这段代码执行得非常慢。 js小提琴相对较快,因为我的示例表只有15行。我的实际表格有100行,可以更改为显示1,000行。
我已经添加了一个控制台日志来测试它执行了多长时间,并且在小提琴中它需要大约15ms来隐藏行,并且~20-40ms再次显示行。< / p>
在我的真实桌子上有100行,这个变化为~300-450ms隐藏和~500-600ms显示。尝试200行(分别为1,200和2,00)时,这个数字增加了一倍多。当我尝试1000行时,我的浏览器几乎崩溃了。
我尝试更改我的代码,以便不改变td
的类名,而是改变了tr
的类名,理论上这意味着jQuery处理所需的处理较少,但这几乎使执行时间翻了一倍,所以我又回到了td
有谁能告诉我如何提高我的代码效率?获得我想要的功能有点令人沮丧,只是让它运行得非常慢。
答案 0 :(得分:2)
使用这种元素迭代时,应该从DOM中分离表。然后,您可以在任务期间向用户显示任何消息,如加载程序。
function resetRows($table) {
var $loader = $('<div id="loader"/>').insertBefore($table),
$tblContent = $table.detach(),
i = 1,
trs = $tblContent.find('tr'),
tds = $tblContent.find('td').removeClass('even odd');
var start = new Date().getTime();
$.each(trs, function (key, index) {
// loop through each table row skipping the first row which will be the title
var tdsRow = $(this).find('td');
if (!$(this).data('hidden') && key > 0) {
if (i % 2 === 0) {
tdsRow.addClass('even');
} else {
tdsRow.addClass('odd');
}
// find the .index class and reset it's value
$(this).find('.index').html(i);
i++;
console.log(i);
}
});
var end = new Date().getTime();
var time = end - start;
$loader.replaceWith($table);
console.log('time taken: ' + time);
}
$(function () {
// show/hide failed
$('#showHideFails').on('click', function () {
if ($('.failed').eq(0).is(':visible')) {
$('.failed, .ins').data('hidden',true).hide();
$('.shTxt').html('Show all');
resetRows($('#table'));
} else {
$('.failed, .ins').data('hidden',false).show();
$('.shTxt').html('Hide failed');
resetRows($('#table'));
}
});
});
答案 1 :(得分:1)
一些代码优化建议:
使用.find()
tds = $(this).find($('td'));
与tds = $(this).find('td')
$('td')
会导致jquery在整个HTML 中搜索所有表格单元格
但你真正想要的是:当前行的所有单元格仅可以用$(this).find('td')
删除“死”代码
如果您在标题行中或者行已被隐藏,那么您的行迭代函数 nothing 。此时您正在搜索该行中的单元格,即使它已被隐藏。
$.each($('tr'), function (key, index) {
if (false == $(this).is(':visible') || 0 == key) {
// skip hidden rows and header row
return;
}
// at this point we know that the current row is visible and not the header row
tds = $(this).find($('td'));
...
});
减少jQuery选择器
据我所知,选择器是这里成本最高的部分。虽然这对于小数据来说不是问题,但它可以影响大型数据,例如1000行等表。尝试使用变量重新使用选择器结果。
将$(this)替换为变量:
var currentRow = $(this);
currentRow.is(':visible');
currentRow.find('td');
...
到目前为止,这是我的想法。请参阅此jsfiddle以获取重写代码:http://jsfiddle.net/5jVdh/3/