vgo*_*ani 15 javascript dom infinite-scroll twitter-bootstrap
我在bootstrap中构建了一个大表,大约5,000行x 10列,我需要使用JavaScript快速过滤表中的特定属性.该表具有id列和属性列,即
id | attr | ...
---------------
2 | X | ...
3 | Y | ...
4 | X | ...
Run Code Online (Sandbox Code Playgroud)
为了快速完成过滤过程,我构建了一个哈希表,将表映射回列ids.例如,我有一个映射:
getRowIds["X"] = [2,4]
Run Code Online (Sandbox Code Playgroud)
用户可以在搜索框中输入属性"X",然后哈希表查找包含"X"的相应行(在本例中为2和4),然后通过映射操作调用以下函数:
this.hideRow = function(id) {
document.getElementById(id).style.display="none"
}
this.showRow = function(id) {
document.getElementById(id).style.display=""
}
Run Code Online (Sandbox Code Playgroud)
此过程仍然很慢,因为允许用户选择多个属性(例如X,Y).
是否有更快的方法来隐藏行?
如果我能以某种方式从DOM分离表,进行更改,然后重新附加,会更快吗?我如何在javascript中执行此操作?
还有其他更有效/更智能的过滤方法吗?
谢谢 :)
我会问
我建议您使用已经执行此操作的多个JavaScript包中的一个.下面两个包有更多的包.我将这两个作为可用内容的示例.
使用AngularJS确实是一个好主意,它让我们可以像下面这样简单地渲染行:
<tr ng-repeat="row in rowArray">
<td>{{row.id}}</td>
<td>{{row.attr}}</td>
</tr>
Run Code Online (Sandbox Code Playgroud)
您只需要提供rowArray
像这样的对象数组{id: 1, attr: 'X'}
,请参阅指令的文档ng-repeat
。其强大的功能之一Angular
在于其极其紧凑的代码。
除此之外,Angular 还拥有强大的过滤器构建库,可以在 HTML 中即时过滤和排序行:
<tr ng-repeat="row in rowArray | yourCustomFilter:parameters">
<td>{{row.id}}</td>
<td>{{row.attr}}</td>
</tr>
Run Code Online (Sandbox Code Playgroud)
话虽如此,将 5K 行放入数组中显然会拖累性能。这会在您的浏览器内存中创建一个巨大的 HTML,但它不适合您的视口。如果无论如何都无法展示出来,那么将其保留在记忆中就没有意义了。相反,您只想在内存中保留可见部分以及周围可能的几行。
看一下 Angular UI Utils提供的指令“滚动直到放下” ——它正是这样做的!
另一个答案中提到的分页肯定是无限滚动的有效替代方案。如果您想深入研究的话,网上有很多关于分页与无限滚动的优点和缺点的文章。
具体来说,您的代码还有其他性能问题。例如,在每次调用时,此函数
document.getElementById(id).style.display="none"
Run Code Online (Sandbox Code Playgroud)
将通过其查找元素的 DOM id
,然后查找其属性(如果 JavaScript 需要在Prototype 链.style
中向上移动,这可能会很麻烦)。您可以通过缓存指向您真正需要的属性的直接引用链接来获得更好的性能。display
编辑。通过在这里缓存,我的意思是预编译具有有趣属性的hash
链接:id
hash[id] = document.getElementById(id).style.display
Run Code Online (Sandbox Code Playgroud)
然后你可以通过简单的设置来切换样式:
hash[id] = 'none'
hash[id] = 'block'
Run Code Online (Sandbox Code Playgroud)
这种计算方式hash
假设你的元素都在 DOM 内部,这对性能不利,但还有更好的方法!
jQuery
当然,像 and 之类的库Angular
可以让您创建具有完整样式属性的 HTML 元素,但无需将它们附加到 DOM。这样您就不会超载浏览器的容量。但您仍然可以缓存它们!因此,您将缓存 HTML(但不是 DOM)元素及其显示,如下所示:
elem[id] = $('<tr>' +
'<td>' + id + '</td>' +
'<td>' + attr + '</td>' +
</tr>');
display[id] = elem[id].style.display;
Run Code Online (Sandbox Code Playgroud)
然后将元素附加/分离到 DOM,并display
使用显示缓存更新其属性。
最后请注意,为了获得更好的性能,您需要首先将行连接成一个束,然后才在一次跳转中附加(而不是逐一附加)。原因是,每次更改 DOM 时,浏览器都必须进行大量重新计算才能正确调整所有其他 DOM 元素。那里发生了很多事情,因此您希望尽可能减少这些重新计算。
后期编辑。
通过一个例子来说明,如果parentElement
已经在你的 DOM 中,并且你想要附加一个新元素数组
elementArray = [rowElement1, ..., rowElementN]
Run Code Online (Sandbox Code Playgroud)
你想要的方式是:
var htmlToAppend = elementArray.join('');
parentElement.append(htmlToAppend);
Run Code Online (Sandbox Code Playgroud)
而不是运行rowElement
一次附加一个的循环。
另一个好的做法是在hide
附加parentElement
之前,然后仅在一切准备就绪时才显示。
归档时间: |
|
查看次数: |
3939 次 |
最近记录: |