如何使用纯Javascript过滤非常大的引导表 [英] How to filter a very large bootstrap table using pure Javascript

查看:68
本文介绍了如何使用纯Javascript过滤非常大的引导表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在bootstrap中构建了一个大表,大约5,000行x 10列,我需要使用JavaScript快速过滤表中的特定属性。该表同时具有id列和属性列,即

I've built a large table in bootstrap, about 5,000 rows x 10 columns, and I need to filter the table for specific attributes, fast, using only JavaScript. The table has both an id column and an attribute column, i.e.

id | attr | ...
---------------
2  |  X   | ...
3  |  Y   | ...
4  |  X   | ...

为了快速完成过滤过程,我构建了一个哈希表表,将表格映射回列ids。例如,我有一个映射:

To make the filtering process fast, I built a hashtable table that maps the attributes back to the column ids. So for example, I have a mapping:

getRowIds["X"] = [2,4]

用户可以在搜索框中输入属性X,然后哈希表会查找包含X的相应行(在这种情况下为2和4),然后通过映射操作调用以下函数:

The user can enter the attribute "X" in a search box, the hashtable then looks up the corresponding rows that contain "X" (2 and 4 in this case), and then calls the following functions via a map operation:

this.hideRow = function(id) {
    document.getElementById(id).style.display="none"
}

this.showRow = function(id) {
    document.getElementById(id).style.display=""
}

此过程仍然相当因为允许用户选择多个属性(比如X,Y)。

This process is still quite slow, as the user is allowed to select multiple attributes (say X,Y).

是否有更快的方法来隐藏行?

Is there a faster way of hiding the rows?

如果我能以某种方式从DOM分离表,进行更改,然后重新附加,会更快吗?我如何在javascript中执行此操作?

Would it be faster if I could somehow detach the table from the DOM, make the changes, and then re-attach? How do I do this in javascript?

是否有其他更有效/更智能的方法进行过滤?

Are there other more efficient/smarter ways of doing the filtering?

谢谢:)

推荐答案

使用 AngularJS 确实是一个好主意,
可让我们将行渲染为简单的

Using AngularJS can indeed be a good idea, which lets us render your rows as simple as

<tr ng-repeat="row in rowArray">
  <td>{{row.id}}</td>
  <td>{{row.attr}}</td>
</tr>

您只需要提供 rowArray 作为 {id:1,attr:'X'} 等对象的数组,请参阅 ng-repeat 指令的文档。其中一个 Angular 的强大功能在于它非常紧凑的代码。

where you only need to supply your rowArray as array of objects like {id: 1, attr: 'X'}, see the documentation for ng-repeat directive. One of Angular's big powers lies in its extremely compact code.

除此之外,Angular还具有强大功能过滤构建库,以便在HTML中即时过滤和排序行:

Among other things, Angular also has powerful filter building library to filter and sort your rows on the fly right inside your HTML:

<tr ng-repeat="row in rowArray | yourCustomFilter:parameters">
  <td>{{row.id}}</td>
  <td>{{row.attr}}</td>
</tr>

话虽如此,将5K行投入阵列显然会造成性能拖累。这将在您的浏览器内存中创建一个巨大的HTML,但是,它不适合您的视口。如果无论如何都无法显示它,那就没有必要把它放在内存中。相反,你只想让你的记忆中的可视部分加上可能还有几行。

Having said that, it'll clearly be a performance drag to throw 5K rows into your array. That would create a huge HTML in your browser memory that, however, will not fit into your viewport. Then there is no point to have it in the memory if you can't show it anyway. Instead you only want to have the viewable part in your memory plus possibly a few more rows around.

查看
提供的指令滚动直到你放弃 Angular UI Utils - 它确实如此!

Have a look at the directive "Scroll till you drop" provided by Angular UI Utils - it does exactly that!

在另一个答案中提到的分页肯定是一个有效的选择无限卷轴。如果你想深入研究,那么网上有很多关于分页与无限卷轴的优缺点的文章。

Pagination as mentioned in another answer is surely a valid alternative to the infinite scroll. There is lot written on the web about strengths and weaknesses of pagination vs infinite scroll if you want to dig into that.

说到你的代码,它有其他性能拖累。
例如,在每次调用时,此函数

Speaking of your code specifically, it has other performance drags. For instance, on each call, this function

document.getElementById(id).style.display="none"  

将通过 id ,然后将查找其属性 .style (如果JavaScript需要在原型链中高位运行,这可能会拖累)。您可以通过将直接引用链接缓存到 display 属性来实现更好的性能,这些属性是您真正需要的属性。

will look up the DOM for the element by its id, and then will look up its property .style (which can be a drag if the JavaScript needs to go high up in the Prototype chain). You could do much better performance wise by caching direct reference links to the display properties, which are the ones you really need.

编辑。
通过缓存在这里我的意思是预编译一个哈希链接 id 和有趣的属性:

EDIT. By caching here I mean pre-compiling a hash linking id with the interesting properties:

hash[id] = document.getElementById(id).style.display

然后通过简单设置切换样式:

Then you switch the style by simple setting:

hash[id] = 'none'
hash[id] = 'block'

这种方式计算哈希假设你的元素都在DOM中,这对性能有害,但有更好的方法!

This way of calculating hash assumes that your elements are all inside the DOM, which is bad for performance, but there are better ways!

jQuery 这样的库,当然还有 Angular :)可以让你创建完整风格的HTML元素属性,但没有将它们附加到DOM 。这样你就不会超出浏览器的容量。但你仍然可以缓存它们!因此,您将缓存您的HTML(但不是DOM)元素及其显示,例如:

Libraries like jQuery and, of course, Angular :) will let you create your HTML elements with their complete style properties but without attaching them to the DOM. That way you are not overloading your browser's capacity. But you can still cache them! So you will cache your HTML (but not DOM) Elements and their Display like that:

elem[id] = $('<tr>' +
  '<td>' + id + '</td>' +
  '<td>' + attr + '</td>' +
</tr>');

display[id] = elem[id].style.display;

然后在你去的时候将你的元素附加/分离到DOM并更新他们的使用显示缓存显示属性。

and then attach/ detach your elements to the DOM as you go and update their display properties using the display cache.

最后请注意,为了获得更好的性能,您希望首先在一个包中连接您的行,然后只在一次跳转中连接(而不是一个一个地连接) )。原因是,每次更改DOM时,浏览器都必须进行大量重新计算才能正确调整所有其他DOM元素。那里有很多,所以你想尽可能地减少那些重新计算。

Finally note that for better performance, you want to concatenate your rows in a bundle first, and only then attach in a single jump (instead of attaching one-by-one). The reason is, every time your change the DOM, the browser has to do a lot of recalculation to adjust all other DOM elements correctly. There is a lot going on there, so you want to minimize those re-calculations as much as possible.

POST EDIT 。

POST EDIT.

举例来说明,如果 parentElement 已经在你的DOM中,并且你想要附加一个数组新元素

To illustrate by an example, if parentElement is already in your DOM, and you want to attach an array of new elements

elementArray = [rowElement1, ..., rowElementN]

您想要的方式是:

var htmlToAppend = elementArray.join('');

parentElement.append(htmlToAppend);

而不是运行附加一个 rowElement 一次。

as opposed to running a loop attaching one rowElement at a time.

另一个好习惯是隐藏你的 parentElement 在附加之前,然后只在一切准备就绪时显示。

Another good practice is to hide your parentElement before attaching, then only show when everything is ready.

这篇关于如何使用纯Javascript过滤非常大的引导表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆