通过 JavaScript 对 HTML 表格进行排序的最有效方法是啥?

Posted

技术标签:

【中文标题】通过 JavaScript 对 HTML 表格进行排序的最有效方法是啥?【英文标题】:What is the most efficient way to sort an HTML table via JavaScript?通过 JavaScript 对 HTML 表格进行排序的最有效方法是什么? 【发布时间】:2012-08-05 16:47:41 【问题描述】:

我正在编写一些 JS 来对 html 表进行排序:HTML 表有一个标题行,单击列的标题会根据该列对行进行排序。我的一般算法如下:

    将 HTML 转换为 javascript 数组。 对 JavaScript 数组进行排序。 将 JavaScript 数组重新转换为 HTML 表格。

现在,我的代码替换了表格的所有 innerHTML 元素。基本上,在对 JS 数组进行排序之后,它会触及表的每个节点,重写它的 innerHTML 值。我觉得可能有更有效的方法可以做到这一点,但我想不出。

编辑:

这是执行上述算法的第 (3) 部分的代码。我编辑了不相关的部分(只是一些字符串转换)。索引有点奇怪,因为我在将表格转换为数组时跳过了标题行,所以我在重写表格时对此进行了补偿。

for (var i = 0; i < numRows-1; i++)
 for (var j = 0; j < numCols; j++)
        var arrCell = tableArr[i][cols[j]];
        tableEl.rows[i+1].cells[j].innerHTML = arrCell;
    

【问题讨论】:

你想只在纯 JS 中实现这个吗? 只要您在内存中生成新标记,然后仅使用 1 个 DOM 操作附加它,这应该是非常有效的。 DOM 修改比 Javascript 数组操作慢。 @Ghillied 是的。我的意思是,在纯 JS 之外有没有更有效的方法来做到这一点?您是否建议我将标题行转换为链接并从服务器重新获取页面并排序表格? @ChrisFrancis 对于 n 个节点的表,我正在执行 n DOM 操作(即我正在重写 innerHTML)。 @Avery 除了纯 JS 之外,没有比这更有效的方法了。我为您提供了一种使用库的方法,但是使用库会在页面中加载额外的千字节(因为您不会使用库中的其他函数)。 【参考方案1】:

您可以从 DOM 中删除行,进行排序,然后将它们添加回 DOM。

var tbody = table.tBodies[0];

var placeholder = document.createElement('tbody');
table.replaceChild(placeholder, tbody);

//sort rows in tbody

table.replaceChild(tbody, placeholder);

【讨论】:

我不知道为什么这被否决了。从 DOM 中删除元素、对其进行大量更改(如按排序移动元素)然后将其添加回 DOM 会更快。这会导致每次移动一行时重绘两次页面,而不是重绘一次页面。【参考方案2】:

使用数组对值进行排序,并使用文档片段来执行更新。

function sortRows(tbody, compare, sortDesc) 
    //convert html collection to array
    var rows = [].slice.call(tbody.rows);
    //sort to desired order
    rows.sort(compare);
    if (sortDesc) 
        rows.reverse();
    
    //update table
    var fragment = document.createDocumentFragment();
    rows.forEach(function (row) 
        fragment.appendChild(row);
    );
    tbody.appendChild(fragment);

复杂性在于比较函数。您需要考虑列索引以及所需的任何类型转换和缓存。

这是一个将单元格文本内容转换为整数的基本示例。

function sortTable(table, columnIndex) 
    while (table && table.tagName !== 'TABLE') 
        table = table.parentNode;
    
    if (table) 
        sortRows(table.tBodies[0], function compare(topRow, bottomRow) 
            var topValue = parseInt(topRow.cells[columnIndex].textContent, 10);
            var bottomValue = parseInt(bottomRow.cells[columnIndex].textContent, 10);
            return (topValue - bottomValue);
        );
    


function sortRows(tbody, compare, sortDesc) 
    //convert html collection to array
    var rows = [].slice.call(tbody.rows);
    //sort to desired order
    rows.sort(compare);
    if (sortDesc) 
        rows.reverse();
    
    //update table
    var fragment = document.createDocumentFragment();
    rows.forEach(function (row) 
        fragment.appendChild(row);
    );
    tbody.appendChild(fragment);
<table>
    <thead>
        <tr><th onclick="sortTable(this, 0)">Sort</th><th onclick="sortTable(this, 1)">Sort</th></tr>
    </thead>
    <tbody>
        <tr><td>1</td><td>25</td></tr>
        <tr><td>3</td><td>12</td></tr>
        <tr><td>2</td><td>40</td></tr>
        <tr><td>10</td><td>25</td></tr>
    </tbody>
</table>

【讨论】:

如果您需要使用 IE8,请将 [].slice.call()、rows.forEach() 和 cell.textContent 替换为跨浏览器方法/属性。【参考方案3】:

您可以使用jQuery 及其Datatables plugin。 在您的数据表语句中,您可以添加

"bSort": true

并且这项工作将由脚本完成。虽然如果你能找到一个纯 JS 的方式我建议你使用它,这样你就不会给你的网页增加无用的重量。

【讨论】:

【参考方案4】:

如果数据存储在服务器上 - 我会向服务器发送一个 Ajax 请求,其排序类型为(ASC、DESC 等),在服务器上对数据进行排序(使用 php 等),然后接收在 JavaScript 中排序数据并全新编写表格。

【讨论】:

以上是关于通过 JavaScript 对 HTML 表格进行排序的最有效方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript小案例-动态表格

使用 JavaScript 对 HTML 表格进行排序

javascript动态添加删除表格

如何通过 JavaScript 获取 html 表格 td 单元格值?

javascript 可以对非常大的表格进行排序、过滤和渲染吗?

html dom与javascript的关系 -我们用JavaScript对网页(HTML)进行的所有操作都是通过DOM进行的