我想要做的是过滤一个表,只显示包含输入到文本框中的值的给定值的tbody,并以斑马条纹图案显示过滤的行。
斑马条纹速度快,过滤速度通常很快,除了在桌子上的第一个过滤器上有很多tbodys(比如2000 tbody?...我没有测量过第一次可见的减速,并且没有' t按数字测试速度,但在Firefox和Chrome中速度很慢)
首先是JS:
//filter results based on query
function filter(selector, query) {
var regex = new RegExp( query, "i" ); // I did this from memory, may be incorrect, but I know the thing works, the problem is the next part, cos on 5 rows it's fast
$(selector).each(function() {
( regex.test( $(this).text() ) ) < 0) ? $(this).hide().removeClass('visible') : $(this).show().addClass('visible');
});
}
// then after this I recall the zebra function, which is fast.
然后是样本数据:
<table>
<thead>
<tr>
<th>value to find 1</th>
<th>value to find 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>12345</td>
<td>67890</td>
</tr>
<tr>
<td>empty for now, while testing</td>
<td>may contain other info later</td>
</tr>
</tbody>
<tbody>
<tr>
<td>23456</td>
<td>78901</td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
<tbody>
<tr>
<td>45678</td>
<td>90123</td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
... /ad nauseum, for 2000 rows +
<tfoot>
</tfoot>
</table>
因此,例如,尝试匹配值123
将返回此示例数据的第一行和第三行,但我认为您已经想到了...
HELP?
答案 0 :(得分:1)
每次使用这么多DOM元素时,主要的性能影响通常都是渲染,因为每次修改DOM中的内容时,浏览器都会重新渲染页面。除非您修改DOM之外的元素,否则这会将渲染性能转换为O(n ^ 2)。有几种方法可以像克隆和DOM数组一样做到这一点。要使用克隆您clone
要修改的元素,请修改克隆元素,然后使用replaceWith
将它们插入到DOM中。 DOM数组只是包含DOM元素的标准JavaScript数组。您可以将DOM元素数组传递给jQuery而不是选择器。这是我使用你的html副本测试的输出。我正在使用jQuery 1.4.2。
// Using chrome 6.0.472.62
Number of <td> elements: 9524
Optimized Time: 232ms
Normal Time: 21669ms
其他现代浏览器具有不同的性能特征。
// Using IE8
Number of <td> elements: 9524
Optimized Time: 1506ms
Normal Time: 4179ms
// Using Firefox 4 Beta
Number of <td> elements: 9524
Optimized Time: 698ms
Normal Time: 2644ms
你可以看到O(n ^ 2)渲染是如何真正开始加起来的。这是我的测试程序减去数千个复制的html元素。
$(document).ready(function(){
console.log("Number of <td> elements: " + $("td").length);
$('input[value=clone]').click(function(){
function filter(selector, query) {
var regex = new RegExp( query, "i" );
var temp = $("table").clone();
var hide = [];
var show = [];
$(selector, temp).each(function() {
if (regex.test($(this).text())) {
hide.push(this);
} else {
show.push(this);
}
});
$(hide).hide().removeClass('visible');
$(show).show().addClass('visible');
$("table").replaceWith(temp);
}
var start = (new Date).getTime();
/* Run a test. */
filter("td","12345");
var diff = (new Date).getTime() - start;
console.log("Optimized Time: " + diff + "ms");
});
$('input[value=normal]').click(function(){
function filter(selector, query) {
var regex = new RegExp( query, "i" );
$(selector).each(function() {
if (regex.test($(this).text())) {
$(this).hide().removeClass('visible');
} else {
$(this).show().addClass('visible');
}
});
}
var start = (new Date).getTime();
/* Run a test. */
filter("td","12345");
var diff = (new Date).getTime() - start;
console.log("Normal Time: " + diff + "ms");
});
});
如果您不想克隆,另一个选项是分离您正在处理的元素,然后在完成后重新附加它们。请参阅detach。
答案 1 :(得分:0)
只是一个想法,这是(双关语)更快吗?
//filter results based on query
function filter(selector, query) {
var regex = new RegExp( query, "i" ); // I did this from memory, may be incorrect, but I know the thing works, the problem is the next part, cos on 5 rows it's fast
$(selector).each(function() {
me = $(this);
( regex.test( me.text() ) ) < 0) ? me.hide().removeClass('visible') : me.show().addClass('visible');
});
}
// then after this I recall the zebra function, which is fast.
应至少按行常数减少2 / 3rds。
另外,你真的需要删除并在每一行上添加一个类 - 如果它被隐藏,你可以检查它是否需要知道它是否可见。
使用jQuery selectory:
//filter results based on query
// all elements in selector must not have class visible set
function filter(selector, query) {
var newSel = selectory+":contains('"+query+"')";
$(newSel).show().addClass('visible');
}
//filter results based on query
// safe version... hides all elements first.
function filter(selector, query) {
$(selector).hide().removeClass('visible');
var newSel = selector+":contains('"+query+"')";
$(newSel).show().addClass('visible');
}
答案 2 :(得分:0)
我认为最好对一组数据使用过滤函数,这些数据就是一个对象数组。然后,您从过滤后的数据提供程序重建表。
显示/隐藏表行存在固有问题,其中最重要的是不同浏览器(我看着你,IE)隐藏不同的事实。仅将行设置为visibility =“hidden”将无法执行您想要的操作。将它设置为display =“none”会,但是你会遇到问题。在这种情况下,您将显示样式设置为什么?当然不是“阻止”。将其设置为表行的行为与跨浏览器的行为不同。