【问题标题】:Sort a table fast by its first column with Javascript or jQuery使用 Javascript 或 jQuery 按第一列快速对表格进行排序
【发布时间】:2011-11-25 08:52:16
【问题描述】:

我有一个从FullCalendar 动态填充的表。 问题是FullCalendar 不关心它的原始顺序。

表格如下所示:

<table id="caltbl">
   <thead>
       <tr> <th> </th>   <th> Date </th>   <th> hours </th>  ... </tr>
   </thead>
   <tbody>
       <tr> <td class="sortnr">1</td>   <td></td> ... </tr>
       <tr> <td class="sortnr">3</td>   <td></td> ... </tr>
       <tr> <td class="sortnr">2</td>   <td></td> ... </tr>
       <tr> <td class="sortnr">4</td>   <td></td> ... </tr>
   </tbody>
</table>

每一行的第一行包含表格应该排序的数字。

我有这个代码来排序:

    var rows = $('#caltbl > tbody').children('tr').detach();

    for (var counter = 1; counter<=rows.length; counter++) {
        $(rows).each(function(index) {
            if ($(this).find(".sortnr").text()==counter){
               $('#caltbl > tbody:last').append($(this));
            }
        });
    }

这在 Firefox 中运行良好,但在 Internet Explorer 中让我非常头疼,因为有 500 多个项目并且它挂起。我可以添加一个setTimeout,但这并不能解决真正的问题。 排序很慢。有什么更快的排序方法?

不必从&lt;table&gt; html 开始,正如我所说,它是动态填充的,所以我有一个包含 html 的Array。每个&lt;tr&gt; 1 个项目(未排序)

【问题讨论】:

  • 在 IE 7(以及更低版本,我猜)中,任何涉及将元素添加到 DOM 的操作都非常慢……这就是问题所在。如何解决它......我不太确定。一种解决方案是在服务器端进行...我意识到 jQuery 自动完成的迟缓,并且有一些关于它的问题,例如:stackoverflow.com/questions/5073612/…
  • 向 DOM 添加东西不是问题。它运行速度极快,而且比 IE7 还要高。问题确实是排序。
  • 谷歌搜索“javascript sort”可以得到一些结果。

标签: javascript jquery performance sorting html-table


【解决方案1】:

我认为你的情况有太多的循环。对于 500 个项目,您将循环 500*500 = 250000 次。没有多少浏览器知道如何做到这一点。

我建议使用 javascript 的原生 array.sort() 方法根据自定义的“比较函数”进行排序。

这是如何完成的(并且很可能可以优化):http://jsfiddle.net/tsimbalar/Dw6QE/。

这个想法是对比较 sortNumber 值的行列表进行排序......

【讨论】:

    【解决方案2】:

    尝试这样的方法: http://jsfiddle.net/qh6JE/

    var rows = $('#caltbl > tbody').children('tr').get(); // creates a JS array of DOM elements
    rows.sort(function(a, b) {  // use a custom sort function
        var anum = parseInt($(a).find(".sortnr").text(), 10);
        var bnum = parseInt($(b).find(".sortnr").text(), 10);
        return anum-bnum;
    });
    for (var i = 0; i < rows.length; i++) {  // .append() will move them for you
        $('#caltbl > tbody').append(rows[i]);
    }
    

    【讨论】:

    • 谢谢,我仍然在自己周围搜索,结果完全一样。但是,IE 仍然挂起。
    【解决方案3】:

    小提琴:http://jsfiddle.net/qNwDe/

    我编写了一种高效的跨浏览器方法来对表中的行进行排序。双循环中的多个 JQuery 选择器会导致严重的性能问题(正如您所注意到的),因此我已经摆脱了 JQuery。

    我的函数的另一个优点是它不介意丢失索引号。我目前指的是每行的第一个单元格,而不是通过类名获取元素。如果你想通过类名来引用,我会改变我的功能:

    function sortTable(){
        var tbl = document.getElementById("caltbl").tBodies[0];
        var store = [];
        for(var i=0, len=tbl.rows.length; i<len; i++){
            var row = tbl.rows[i];
            var sortnr = parseFloat(row.cells[0].textContent || row.cells[0].innerText);
            if(!isNaN(sortnr)) store.push([sortnr, row]);
        }
        store.sort(function(x,y){
            return x[0] - y[0];
        });
        for(var i=0, len=store.length; i<len; i++){
            tbl.appendChild(store[i][1]);
        }
        store = null;
    }
    

    只要您想对表格进行排序,请致电sortTable()。

    【讨论】:

    • 我猜这个选项比 mblase75 更快,因为它不使用 jQuery find()
    • @Stefanvds mblase75 的算法非常低效,因为它使用了.find 函数在 sort 函数中。此外,他在for 循环中使用$("#calctbl &gt; tbody") inside,这在一张非常大的桌子上加起来需要几秒钟。正如我在回答中所说,对于这种情况,JQuery 是一个糟糕的解决方案。
    • 我已将其付诸实践。它非常快。在几秒钟内对 600 行进行排序,并且 IE 不会挂起。杰出的!我知道 jQuery 不是为此而生的。这就是我问 stackoverflow 的原因 :) 谢谢伙计!
    • 作为一个小提示,一个表可以有多个&lt;tbody&gt; 元素。
    • @Rob W 感谢您在上面提供的功能,我已经使用了几个星期,效果很好。我遇到了一个问题,我现在尝试使用您的函数对表进行排序,然后还根据另一列中的 值对第一列中找到的任何匹配值进行排序。基本上对初始排序中找到的匹配项使用“子排序。您可以提供任何输入来改变您的功能来做到这一点?谢谢
    【解决方案4】:

    查看http://square.github.com/crossfilter/ Square 的团队使用了一种巧妙的位图索引技术,允许在

    【讨论】:

      【解决方案5】:

      对于 Rob W 回答的相同问题,我们可以使用 jquery insead of javascript。它不会影响任何性能问题,例如双循环中的多个 JQuery 选择器。

      var $tbody = $('table tbody');
                  $tbody.find('tr').sort(function (a, b) {
                      var tda = $(a).find('td:eq(' + ColumnIndex + ')').text(); // Use your wished column index
                      var tdb = $(b).find('td:eq(' + ColumnIndex + ')').text(); // Use your wished column index
                      // if a < b return 1
                      return tda > tdb ? 1
                             // else if a > b return -1
                             : tda < tdb ? -1
                             // else they are equal - return 0    
                             : 0;
                  }).appendTo($tbody);

      降序使用 。

      FIDDLE

      【讨论】:

      • 高效。它还根据第一列的文本/单词排列/重新排序
      • 这个 sn-p 使用字符串值进行排序(例如 1、5、44 将被排序为 1、44、5)。您可以在返回之前包含if(!isNaN(tda) &amp;&amp; !isNaN(tdb)) return parseInt(tda) - parseInt(tdb);,以便您的代码也可以处理整数排序。 Fiddle
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-30
      • 2016-05-09
      • 1970-01-01
      • 1970-01-01
      • 2014-07-24
      • 2021-05-28
      • 2016-01-06
      相关资源
      最近更新 更多