Javascript 有效地在 HTML 中显示大列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10989686/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Efficiently showing large list in HTML
提问by jhchen
Is there a javascript library that efficiently loads a giant list by only loading the viewable part of that list and faking the scrollbar?
是否有一个 javascript 库可以通过仅加载该列表的可见部分并伪造滚动条来有效加载一个巨大的列表?
<div id='container'>
<!-- Empty but height is set to take up space to fake scrollbar -->
<div id='hidden-before'></div>
<!-- Preloaded in case the user scrolls up -->
<div id='preload-before'></div>
<!-- User can see this. Height == #container's height -->
<div id='viewable-section'></div>
<!-- Preloaded in case the user scrolls down -->
<div id='preload-after'></div>
<!-- Empty but height is set to take up space to fake scrollbar -->
<div id='hidden-after'></div>
</div>
Google Docs for example does this for large text documents.
例如,Google Docs 为大型文本文档执行此操作。
Note: What I am looking for is more complex than infinite scroll. Infinite scroll just waits for you to hit the bottom and it will load more data, enlarging the scrollbar. What I'm looking for will make you think all the data has been loaded because the scrollbars are faked. When you hit the bottom, you've actually hit the end of the list I want to show.
注意:我正在寻找的东西比无限滚动更复杂。无限滚动只是等待您点击底部,它会加载更多数据,扩大滚动条。我正在寻找的东西会让您认为所有数据都已加载,因为滚动条是伪造的。当你到达底部时,你实际上已经到达了我想要展示的列表的末尾。
采纳答案by Denis
回答by Shyam Habarakada
I ran into a similar problem. The scenario was that I already had a large (~400+ elements) to be displayed in a list, where each element can have it's own view. The creation, layout and painting of the DOM for those elements was slower than I needed when tryign to render the entire list inside a scrolling DIV.
我遇到了类似的问题。场景是我已经有一个大的(~400+ 个元素)要显示在列表中,其中每个元素都可以有自己的视图。当尝试在滚动 DIV 中渲染整个列表时,这些元素的 DOM 的创建、布局和绘制比我需要的要慢。
I looked at several solutions.
我看了几个解决方案。
InfinityJS[1] was pretty close to what I wanted except it required that the element containing the list items already be added to the DOM.
InfinityJS[1] 与我想要的非常接近,只是它要求包含列表项的元素已经添加到 DOM 中。
infinite-scroll[2] by Paul Irish was also interesting, but was solving a specific problem that was different from what I needed to solve.
Paul Irish 的无限滚动[2] 也很有趣,但它正在解决一个与我需要解决的问题不同的特定问题。
MegaList[3] came closest to what I wanted. Andrew (author) has done a great job of designing it for mobile first, with touch support etc. One caveat for me was that it appears to assume a strict selection list model and does a little bit more than I'd like a list component to do (e.g. binding to resize events and trying to handle that automatically).
MegaList[3] 最接近我想要的。安德鲁(作者)在首先为移动设备设计,支持触摸等方面做得很好。对我来说,一个警告是它似乎假设了一个严格的选择列表模型,并且比我想要的列表组件做的多一点要做(例如绑定到调整大小事件并尝试自动处理)。
So I started writing a barebones list component losely modeled after the iOS UITableView -- and called is the js-virtual-list-view (vlv :-). It's a work in progress and I wouldn't recommend it over the above unless you have similar needs that aren't quite met with those.
所以我开始编写一个以 iOS UITableView 为模型的准系统列表组件——它被称为 js-virtual-list-view (vlv :-)。这是一项正在进行中的工作,除非您有类似的需求但没有完全满足这些需求,否则我不会推荐它。
Sources are here https://github.com/shyam-habarakada/js-virtual-list-view.
来源在这里https://github.com/shyam-habarakada/js-virtual-list-view。
Contributors needed :-)
需要贡献者:-)
[1] http://airbnb.github.io/infinity/
[1] http://airbnb.github.io/infinity/
[2] http://www.infinite-scroll.com/
[2] http://www.infinite-scroll.com/
回答by voithos
It's a technique called "infinite scroll", and multiple libraries support it. If you're using jQuery, take a look at:
这是一种称为“无限滚动”的技术,并且有多个库支持它。如果您使用 jQuery,请查看:
http://www.infinite-scroll.com/
http://www.infinite-scroll.com/
As you know, the idea is to determine "how much" of the dataset the user can current see, and then perform a request for onlythat much, but set the scroll in relation to the size of the entire set. That way, once the user scrolls past a certain point, you can request for the next part of the dataset.
如您所知,这个想法是确定用户当前可以看到的“多少”数据集,然后仅执行该数量的请求,但根据整个集合的大小设置滚动。这样,一旦用户滚动经过某个点,您就可以请求数据集的下一部分。
ExtJS also has this as part of their component-based framework. Here's a grid example.
ExtJS 也将此作为其基于组件的框架的一部分。这是一个网格示例。
回答by Jr Phillips
Have you tried the overflow attribute in css? Just give your container div a standard width and height like so:
您是否尝试过 css 中的溢出属性?只需给你的容器 div 一个标准的宽度和高度,如下所示:
#container { height: 500px; width: 500px; overflow: auto;}
#container { 高度:500px; 宽度:500px;溢出:自动;}
回答by elliotcw
This post covers your question and presents answers - http://engineering.linkedin.com/linkedin-ipad-5-techniques-smooth-infinite-scrolling-html5
这篇文章涵盖了您的问题并提供了答案 - http://engineering.linkedin.com/linkedin-ipad-5-techniques-smooth-infinite-scrolling-html5
Isn't the killer plugin you're after but goes a long way to explaining how you would go about creating it yourself.
这不是您所追求的杀手级插件,而是在很大程度上解释了您将如何自己创建它。
UPDATE: There's a new library called infinity.js, more info here - https://stackoverflow.com/a/12108015/921259
更新:有一个名为 infinity.js 的新库,更多信息在这里 - https://stackoverflow.com/a/12108015/921259
回答by Lukasz Matysiak
You can look into using Polymer's <iron-list>
which actually consumes all the data but it only attaches a handful of nodes to the DOM and handles data binding to display the right content as the user scrolls through.
您可以考虑使用 Polymer <iron-list>
,它实际上消耗了所有数据,但它只将少数节点附加到 DOM 并处理数据绑定以在用户滚动时显示正确的内容。
I've used it before and got very good results with custom lists of 2000+ items (those items being complex custom elements too) scrolling seamlessly.
我以前使用过它,并且通过无缝滚动的 2000 多个项目(这些项目也是复杂的自定义元素)的自定义列表获得了非常好的结果。
Though I haven't tried it myself the Polymer team claims it can be easily mixed with other frameworks.
虽然我自己没有尝试过,但 Polymer 团队声称它可以很容易地与其他框架混合使用。
https://www.webcomponents.org/element/PolymerElements/iron-list
https://www.webcomponents.org/element/PolymerElements/iron-list
回答by StefansArya
It's true that you will have performance cost when scrolling a large list. Even if you set display:none;
or visibility:hidden;
to every element that was not visible on the viewport, you will have some lag because every element still being recalculated when you scrolling the list.
滚动大列表时确实会产生性能成本。即使您为视口上不可见的每个元素设置display:none;
或visibility:hidden;
,也会有一些滞后,因为滚动列表时每个元素仍在重新计算。
To avoid the recalculation, every element should be moved to Virtual DOM so it will never being rendered and some property (like height/width) will default to 0
.
为了避免重新计算,每个元素都应该移动到虚拟 DOM 中,这样它就永远不会被渲染,并且某些属性(如高度/宽度)将默认为0
.
There are some library that can handle the virtual scroll like Clusterize, ngx-ui-scroll, hyperlist, etc.
有一些库可以处理虚拟滚动,如Clusterize、ngx-ui-scroll、hyperlist等。
But some of them doesn't support dynamic row height, some of them aren't MIT licensed, and some of them have a little feature for manipulating the content list. So I decided to build a MVW librarythat can handle dynamic row height like this example. And yes, it's able to use scrollTo(index)
for automatically scroll to the selected index.
但其中一些不支持动态行高,其中一些未获得 MIT 许可,而其中一些具有用于操作内容列表的小功能。所以我决定构建一个可以像这个例子一样处理动态行高的MVW 库。是的,它能够用于自动滚动到选定的索引。scrollTo(index)
The implementation is just like
实现就像
<div sf-controller="large-list">
<ul class="sf-virtual-scroll">
<li sf-repeat-this="x in list">
{{x.id}}
</li>
</ul>
</div>
sf.model.for('large-list', function(self){
self.list = [];
for(var i = 0; i < 1000; i++){
self.list.push({id:i});
}
});
You could manipulate the displayed list with the default array function like push
, splice
, pop
.
您可以使用默认数组函数(如push
, splice
, )操作显示的列表pop
。
Or try it here
或者在这里试试