Быстрая сортировка таблицы по ее первому столбцу с помощью Javascript или jQuery - PullRequest
23 голосов
/ 26 сентября 2011

У меня есть таблица, которая динамически заполняется от 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, но это не решило бы реальную проблему. Сортировка медленная. Какой способ быстрее это отсортировать?

Вместо того, чтобы начинать с html <table>, как я сказал, он заполняется динамически, поэтому у меня есть Array, который содержит html. 1 предмет за <tr> (не отсортировано)

Ответы [ 5 ]

51 голосов
/ 26 сентября 2011

Fiddle : 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() всякий раз, когда вы хотите отсортировать таблицу.

7 голосов
/ 26 сентября 2011

Попробуйте такой подход: 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]);
}
5 голосов
/ 26 сентября 2011

Я думаю, что в вашем случае слишком много петель. С 500 предметами вы бы зациклились 500 * 500 = 250000 раз. Не так много браузеров знают, как это сделать.

Я предлагаю использовать собственный array.sort() метод javascript для выполнения сортировки на основе пользовательской «функции сравнения».

Вот как это можно сделать (и, скорее всего, это можно оптимизировать): http://jsfiddle.net/tsimbalar/Dw6QE/.

Идея состоит в том, чтобы отсортировать список строк, сравнивая значение sortNumber ...

1 голос
/ 28 января 2015

Мы можем использовать JQuery Inadad 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

1 голос
/ 09 мая 2012

Проверьте это http://square.github.com/crossfilter/ команда в Square использовала умную технику индекса растрового изображения, чтобы позволить фильтровать данные размером 5,3 МБ за <30 мс ... Я не уверен, помогает ли это, но это очень интересная техника </p>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...