在浏览器中有效地表示一个大网格
Posted
技术标签:
【中文标题】在浏览器中有效地表示一个大网格【英文标题】:Efficiently representing a large grid in a browser 【发布时间】:2011-01-18 20:25:00 【问题描述】:我需要在浏览器中显示和操作最多包含 10,000 个简单单元格(例如 100 x 100)的网格。这些单元格基本上只是一个彩色矩形。操作包括使用 javascript 更改单元格颜色、处理对每个单元格的点击等。使用每个单元格 1 个 div 和 1 个 div 将单元格组包装成一行,我可以减少到基本上 10,000 个 DOM 元素,但这仍然相当很多。我担心更快的 DOM 函数的性能,比如getElementById
。
最初的问题:如果我将所有必要的 DOM 元素引用存储在一个 Javascript 数组中(例如,一个 10,000 个元素的数组,每个单元格一个元素)并在每个元素的基础上操作 CSS,这是否有一个祈祷当 DOM 有 200 到 500 个元素时,它会像它一样快吗?
所以,我正在寻找有关如何更有效地显示这个 100 x 100 网格的建议。我考虑过使用canvas
并使用Javascript 绘制每个单元格,但我不确定这实际上会快多少,尤其是在需要编辑单元格样式的时候。我也不太倾向于使用canvas
,因为它不是完全交叉兼容的(阅读:@#%$ing IE),在某些时候我可能需要让这个东西与 IE 兼容。
你有什么想法?
【问题讨论】:
【参考方案1】:请参阅JavaScript data grid for millions of rows,或者简而言之,使用 SlickGrid - http://github.com/mleibman/slickgrid
【讨论】:
Slickgrid 项目已死(至少已停止)。任何如此有效的替代方案? 它没有死。虽然我现在没有时间专门支持它并添加新功能,但它仍然可用,而且 GitHub 上还有一个拥有 1500 多个分支的蓬勃发展的生态系统。【参考方案2】:不管怎样,您可以使用边框让一个<div>
代表三个或更多区域。虽然确保跨浏览器兼容性会很尴尬(考虑到 Trident、Gecko、Webkit 和 Presto 之间的差异)。
如果单元格在其演示文稿中基本上是表格形式,那么您可以使用表格。这会稍微简化一些事情,尽管根据您的用例可能是非语义的。
另外,我个人会使用您可用的选项来测试创建它,用于表格、div、列表(可能是ul
,但这当然取决于您的用例)......然后选择你认为最快的。
我建议使用 CSS 精灵作为每个单元格的背景/颜色,如果它们将是可预测的高度宽度,只是为了节省一些带宽。
针对cmets中的问题:
让一个div
为三个区域生成颜色,假设每个div
的固定高度/宽度为 100 像素。
div#3areas
width: 100px;
height: 100px;
background-color: #f00; /* for the vertically-centred area */
border-top: 100px solid #00f;
border-bottom: 100px solid #0f0;
应该生成类似的东西:
+------------------------+
| |
| border-top |
| (#00f |
+------------------------+
| |
| central content |
| area (#f00) |
+------------------------+
| |
| border-bottom |
| (#0f0) |
+------------------------+
但它可能不会,由于浏览器处理边框的方式不同,请参阅:http://www.cssplay.co.uk/boxes/borders.html(尽管这是相当过时的,是在 IE6、Mozilla 1.5 和 Netscape 7 时编写的被认为值得评论)。
【讨论】:
单元格是表格的,但使用 CSS 设置样式有点麻烦——这就是我使用 div 的原因,它给了我相同数量的 DOM 元素,但更容易设置样式。背景只是一种 CSS 颜色,因此不需要精灵。 如何使用边框让一个div
代表多个区域?【参考方案3】:
jsgraphics 演示了使用 div 进行 2d 绘图。在最坏的情况下,每个 div 都是一个像素,它可以在画布上管理数千个。
另一种选择是只显示用户当时可以看到的内容。像虚拟滚动区域库之类的东西可能会有用。这个想法是只为用户可以看到的区域渲染(创建 div)。 google
【讨论】:
以上是关于在浏览器中有效地表示一个大网格的主要内容,如果未能解决你的问题,请参考以下文章