在性能方面遇到困难时,我该如何将其更改为用于循环
Struggling with performance how do I change this to use for loops?
我有一个函数,用于检查edit-error
类表每行中的每个单元格。如果在特定行的任何单元格中都发现了这种情况(单元格值尚未通过验证),那么我将从整行中删除edit-submit
类,并取消选中该行第一个td
中的复选框。
当有大量行(1000+)时,我会在性能上遇到困难,所以我想我可以尝试循环,但我不是JavaScript专家,所以我正在寻求帮助。
原始代码如下:
var checkErrors = function () {
$('#results tr:not(:first)').each(function () {
$('td:first input:checkbox', $(this)).attr('checked', 'checked');
$(this).addClass('edit-submit');
$(this).find('td').each(function () {
if ($(this).hasClass('edit-error')) {
$('td:first input:checkbox', $(this).parent('tr')).removeAttr('checked');
$(this).parent().removeClass('edit-submit');
}
});
});
}
该表的id为#results
。我首先要做的是检查所有复选框,并将edit-submit
类添加到每一行,然后循环检查所有单元格中的错误。
我正在寻求任何有关此功能性能改进的帮助。
编辑
添加表html是有意义的。对此深表歉意:
<table id="results">
<tbody>
<tr>
<th> </th>
<th>Policy Number</th>
<th>Quota Code</th>
<th>Contract Date</th>
</tr>
<tr>
<td><input type="checkbox"></td>
<td class="edit-error">ABC123%</td>
<td>123</td>
<td class="edit-error">99/99/9999</td>
</tr>
<tr class="edit-submit">
<td><input type="checkbox" checked="checked"></td>
<td>ABC123</td>
<td>123</td>
<td>16/03/2012</td>
</tr>
</tbody>
</table>
这将显示在页面上:
--------------------------------------------------||保单号|额度编码|合同日期|--------------------------------------------------||ABC123%|123 |99/99/9999|--------------------------------------------------|X | ABC123 | 123 | 2012年3月16日|--------------------------------------------------
有几种方法可以在不使用普通JS for循环的情况下加快代码的速度。仅举几个例子:
- 您已经在外部
.each()
循环中引用了当前行,因此请使用它,而不是在内部循环中调用$(this).parent()
- 如果只想处理具有特定类的td元素,可以在选择器中包含该类,而不是调用
.hasClass()
- 通过存储对返回的jQuery对象的引用和/或通过链接,避免多次调用同一选择器
- 当提供上下文作为
$()
的第二个参数时,您可以直接传递DOM元素或this
,而无需将其封装在另一个$()
调用中 - 如果你知道总是有一个复选框,你可以直接取消选中它来保存函数调用
因此:
var checkErrors = function () {
$('#results tr:not(:first)').each(function () {
var $tr = $(this),
cb = $('td:first input:checkbox', this)[0];
cb.checked = true;
$tr.addClass('edit-submit')
.find('td.edit-error').each(function () {
cb.checked = false;
$tr.removeClass('edit-submit');
});
});
};
然而,根本不需要tds上的内部循环,因为您只需要测试错误类所在的行中是否有tds,而不需要实际循环所有tds。此外,为了更好地衡量,这里有一种使用for循环而不是.each()
的方法-请注意,如果您只选择所有行,然后从第二行开始循环,则可以避免复杂的非第一选择器:
var checkErrors = function () {
var $rows = $('#results tr'),
i;
for (i = 1; i < $rows.length; i++) {
var $tr = $rows.eq(i),
cb = $tr.find('td:first input:checkbox')[0];
if ($tr.find('td.edit-error').length === 0) {
cb.checked = true;
$tr.addClass('edit-submit');
} else {
cb.checked = false;
$tr.removeClass('edit-submit');
};
}
};
尝试为$(this)设置一个变量。您还需要使用find('td')吗?$('td',this)会做同样的事情但更有效吗?
试试这个:
$.each($('#results .edit-error').parent(),function(){
$(this).removeClass('edit-submit').find('td:first-child input:checkbox').removeAttr('checked');
});
为$(this)使用一个变量。
您的选择器也可以改进:使用$('#that').find('#this')
而不是$('#this', '#that')
以下是经过这些优化的改进版本。
var checkErrorsOptimized = function () {
$('#results tr:not(:first)').each(function () {
var $this = $(this);
$this.find('td:first input:checkbox').attr('checked', 'checked');
$this.addClass('edit-submit');
$this.find('td').each(function () {
var $that = $(this);
if ($that.hasClass('edit-error')) {
$that.parent('tr').find('td:first input:checkbox').removeAttr('checked');
$that.parent().removeClass('edit-submit');
}
});
});
}
你可以在这个jsFiddle上看到它(使用Firebug评测):http://jsfiddle.net/5kBsU/3/
- 如何重写下面的函数,使其不会't用于循环
- 对于循环-在循环内部循环,用于获取带有ascii值的字母表
- 用于使用javascript循环选择选项
- 用于循环随机返回的javascript
- Javascript-用于展开数组的递归/for循环
- 用于异步函数中的循环和定时问题
- 函数式编程 - 用于递增计数器的简单 for 循环
- `用于调试无尽循环的“普通语法”
- 用于循环的 Javascript 来检查间隔重叠
- 带有Javascript的正则表达式,用于从循环中检索内容
- 用于循环和匹配字符串的 JavaScript
- 为什么循环内容轮播jQuery插件不适用于Bootstrap 3
- 用于循环的 Javascript 过早结束
- 用于动态创建对象的嵌套循环
- 在'用于'如果javascript中不存在对象属性,则循环
- angularjs用于生日字段的循环
- JavaScript循环(用于每个或每个)
- Jquery循环用于定时横幅动画
- R中的For循环用于数据编译
- 在CasperJS中,Do for循环用于等待某些东西