我有一个包含非常大的表(几千行)的页面。
该表显示了某些过滤器指定的数据子集。每当其中一个过滤器发生变化时,我都需要更新表格。
基本上,有一些复选框和一个文本框,只要其中一个更改我重新加载表格,只显示那些符合用户指定条件的行。
我这样做是通过清除表并重新加载与过滤器匹配的行来实现的。这有效,但事实证明非常慢。
这是我的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]);
}
}
有没有办法让它更快?
答案 0 :(得分:1)
好吧,抱歉延误了,但我被卷起了工作。我提出了一套很好的逻辑来说明你需要什么。
我创建了一些简单的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>
log div只是为了显示输出,我认为这会有所帮助。每行由类'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,否则它将保持为假。
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';
}
}
无论如何,这可以被清理并且当然是优化的,但我认为意图和逻辑是相当清楚的。希望这有助于并随意质疑其中任何一个:)