具有大量行的表更新速度很慢
Table with large number of rows is slow to update
我有一个页面,里面有一个非常大的表(有几千行)。
表显示由某些过滤器指定的数据子集。当其中一个过滤器发生变化时,我需要更新表。
基本上,有几个复选框和一个文本框,每当其中一个更改时,我重新加载表以只显示符合用户指定条件的行。
我通过清除表并重新加载匹配过滤器的行来做到这一点。这是有效的,但已被证明是非常缓慢的。
下面是我的javascript代码:
function reloadTable() {
var tablebody = document.getElementById("tablebody");
while(tablebody.hasChildNodes()) tablebody.removeChild(tablebody.firstChild);
filter = new FilterChecker();
for (var i=0;i<rows.length;i++) {
if (filter.isVisible(rows[i]))
addRowToTable(rows[i]);
}
}
有办法使它更快吗?
好吧,抱歉耽误了,我工作太忙了。我想出了一套很好的逻辑来说明你需要什么。
小提琴我创建了一些简单的html来说明这一点。它包含两个下拉菜单来模拟过滤器和8个数据行来模拟您的数据网格。
<div id="body">
<select id="filterA" class="filter" name="states">
<option value="filterACT">Connecticut</option>
<option value = "filterAMA">Mass</option>
</select>
<select id="filterB" class="filter" name="towns">
<option value="filterBBT">Big Town</option>
<option value = "filterBST">Small Town</option>
</select>
<div id="grid">
<div class="row filterACT filterBBT">BigTown CT 1</div>
<div class="row filterACT filterBBT">BigTown CT 2</div>
<div class="row filterACT filterBST">SmallTown CT 1</div>
<div class="row filterACT filterBST">SmallTown CT 2</div>
<div class="row filterAMA filterBBT">BigTown MA 1</div>
<div class="row filterAMA filterBBT">BigTown MA 2</div>
<div class="row filterAMA filterBST">SmallTown MA 1</div>
<div class="row filterAMA filterBST">SmallTown MA 2</div>
</div>
</div>
</br>
<hr/>
<div>LOG</div>
<hr/>
<div id="log"></div>
logdiv只是为了显示一个输出,我认为这会很有帮助。每一行都由类"row"标识,后面跟着另一系列类。这些类帮助确定它们的筛选器数据是什么。您需要在构建网格时以编程方式设置它。此外,这些类名必须与过滤器选项值匹配。您可以看到,第一行有来自filterA中的第一个选项和filterB中的第一个选项的类。
现在,javascript有点冗长,但您可以重构您的内心内容。有时我发现,当你试图理解事情的时候,如果事情是明确的,会更容易一些。同样,不可否认的是,我会用jQuery来做这件事,所以我的纯Javascript不是那么清晰。
var elements = document.getElementsByClassName('filter');
writeToLog("Filter elements found: " + elements.length);
for(var e = 0;e < elements.length;e++)
{
elements[e].onchange =function() {
writeToLog('Filter event fired for id:'+this.id);
filterChange();
};
}
首先我得到所有的元素与过滤器类,这将是你的过滤器。然后遍历它们并设置它们的onchange事件以调用filterChange()方法。writeToLog()方法调用只是为了输出。
function filterChange() {
var filterClasses = [];
for(var i = 0;i<elements.length;i++) {
writeToLog('Pushing ('+elements[i].value+') into filter class variable.');
filterClasses.push(elements[i].value);
}
在函数的第一部分,我得到所有的选择过滤器选项值,并把它们放入一个数组。
writeToLog('Filter classes: ' + filterClasses);
var rows = document.getElementsByClassName('row')
writeToLog('Row count: ' + rows.length);
然后我得到所有的行,在我的网格中,并开始迭代它们:
for(var j = 0;j<rows.length;j++)
{
writeToLog('Checking row: ' + rows[j].className);
var rowIsHidden = false;
一旦我有了一行,在循环中,我迭代数组中的过滤器类,看看这一行的类是否有它。如果不是,我将rowIsHidden设置为true,否则保持false。
for(var k = 0;k<filterClasses.length;k++)
{
writeToLog('Checking for class: ' + filterClasses[k]);
if(rows[j].className.indexOf(filterClasses[k]) < 0)
{
writeToLog('Class not found, hide this row.');
rowIsHidden = true;
break;
}
}
在循环移动到下一行之前,我基于rowIsHidden值设置了显示样式。
writeToLog('Row is hidden: ' + rowIsHidden);
rows[j].style.display = rowIsHidden ? 'none' : 'block';
}
}
无论如何,这可以被清理和优化,但我认为意图和逻辑是相当清楚的。希望这对你有所帮助,如果有任何问题,请随时提问:)
- Javascript循环不会自我更新
- 添加文字和评论功能更新Div
- AngularJS:ng之后,重复$scope值未按预期更新
- 如何通过数组更新角度子范围
- Ajax聊天消息重复而不仅仅是更新
- 通过CSV文件上载更新数据库表
- 平均值:无法将数据更新到数据库
- $rootScope未使用forEach进行更新
- d3基于用户选择动态更新节点
- 有条件更新d3.js力图中节点的最佳方法
- Angular:更新一次性绑定的数据
- Javascript更新孙窗口中的表单元素
- animate() 更新速度不够快
- 在不改变循环速度的情况下更改更新速度
- 从用PHP脚本创建的json对象更新速度表数据
- WebKit浏览器更新画布的速度很慢
- 具有大量行的表更新速度很慢
- 改变在IE 11中不工作的DIV的旋转速度,使用JS来更新CSS动画属性
- 动画运行时更新动画速度
- chrome的DOM更新速度比firefox慢,看起来chrome有一些渲染问题