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では正常に機能しますが、500を超えるアイテムがありハングするため、Internet Explorerで大きな頭痛の種になります。 setTimeout
を追加することはできますが、実際の問題は解決しません。 ソートが遅い。これをソートするより速い方法は何ですか?
<table>
htmlから開始する代わりに、動的に入力されるので、htmlを含むArray
があります。 <tr>
あたり1アイテム(未ソート)
フィドル: 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()
を呼び出してください。
次のようなアプローチを試してください。 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]);
}
あなたの場合、ループが多すぎると思います。 500アイテムの場合、500 * 500 = 250000回ループします。それほど多くのブラウザはそれを行う方法を知っていません。
ネイティブの array.sort()
javascriptのメソッドを使用して、カスタムの「比較関数」に基づいてソートを行うことをお勧めします。
これがどのように行われる可能性があるか(そしておそらく最も最適化できる): http://jsfiddle.net/tsimbalar/Dw6QE/ 。
アイデアは、sortNumber値を比較する行のリストをソートすることです...
これを確認してください http://square.github.com/crossfilter/ Squareのチームは、賢いビットマップインデックス手法を使用して、<30msで5.3MBデータをフィルタリングできるようにしています...これが役立つかどうかはわかりませんが、非常に興味深いテクニックです
Rob Wが答えたのと同じことに対して、javascriptのjqueryを使用できます。ダブルループの複数の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);
降順では>の代わりに<を使用します。