本文所實現的表格排序大致可以分爲以下幾個步驟:
1、取得要排序的所有行,將其引用push到一個數組中
2、根據要排序的行的情況編寫數組排序時使用的比較函數
3、對包含所有行引用的數組進行排序
4、將排序後的數組按照指定的順序把數組所引用的行重新寫回DOM
如果您對使用DOM操作表格還不太熟悉,您可以參考一下《使用DOM編寫瀏覽器兼容的Table操作》,如果您對數組的排序還不太熟悉,可以參考一下《數組排序以及在漢字排序中localeCompare()方法的使用》,因爲使用DOM操作表格和數組排序是表格排序的基礎。
先看一下我們示例用的代碼,本文會按照上面提到的步驟一步一步的分析:
1 var asc = true;
2 var arrayTr = []; //存放所有要排序的行引用的容器
3 function sortTable(){
4 //取得所有要排序的行
5 var oTable = document.getElementById("oTable");
6 var oTBody = oTable.tBodies[0];
7 var allTr = oTBody.rows;
8 //將要排序的行放入數組以排序
9 for(var i=0;i<allTr.length;i++){
10 arrayTr.push(allTr[i]);
11 }
12 //如果是升序
13 if(asc){
14 arrayTr.sort(compareFunc);
15 oTable.rows[0].title = "點擊降序排列表格";
16 asc = false;
17 } else {
18 //如果是降序
19 arrayTr.reverse();
20 oTable.rows[0].title = "點擊升序排列表格";
21 asc = true;
22 }
23 //將排過續的行按照數序重寫回DOM
24 var oFragment = document.createDocumentFragment();
25 for(var j =0; j < arrayTr.length;j++){
26 oFragment.appendChild(arrayTr[j]);
27 }
28 oTBody.appendChild(oFragment);
29 } 程序的5--11行實現了我們所說的第一步,這裏有兩個需要說明的地方,一是我們在HTML中使用了<thead/>和<tbody />標籤用於分割表格的標題本分以及要排序的部分,礙於篇幅HTML代碼不再展示,二是《JavaScript高級程序設計》說Table的 tBodies屬性是一個JS中的集合,而不是數組,沒有sort()方法,所以不能用來直接排序,關於JS集合的概念還需要我們好好研究啊,不過這不是本文的重點,這裏我們想說明的重點是,tBodies不能拿來直接排序。
程序的13--22行實現了第三步,這裏我們隱藏了第二步的具體實現(在後面的部分會詳細說明)我們認爲這樣可以更好的說明我們的思路,而不會讓自己糾纏於具體的方法實現導致對程序沒有一個總體的認識。還要說明的是程序中我們使用了一個全局性的容器來裝載排序行,所以函數執行後,arrayTr總會包含最後一次排序的行引用順序,這時如果我們想進行倒序的話只需調用reverse()方法,而不再需要對數組進行逆向排序。
程序的24行使用了document.createDocumentFragment()可以得到一個文檔碎片,documentFragment是一個不完整的document對象,主要用於存放暫時沒有加入dom樹的Element。作爲js操作dom的緩存,十分好用,他會一次性的將改動在DOM中呈現,而不是每次操作DOM都要是客戶端重繪。
下面看用於實現我們第二步的函數的具體實現:
function compareFunc(oTr1,oTr2){
1 var param1 = oTr1.cells[0].childNodes[0].nodeValue;
2 var param2 = oTr2.cells[0].childNodes[0].nodeValue;
3 //如果兩個參數均爲字符串類型
4 if(isNaN(param1) && isNaN(param2)){
5 return param1.localeCompare(param2);
6 }
7 //如果參數1爲數字,參數2爲字符串
8 if(!isNaN(param1) && isNaN(param2)){
9 return -1;
10 }
11 //如果參數1爲字符串,參數2爲數字
12 if(isNaN(param1) && !isNaN(param2)){
13 return 1;
14 }
15 //如果兩個參數均爲數字
16 if(!isNaN(param1) && !isNaN(param2)){
17 if(Number(param1) > Number(param2)) return 1;
18 if(Number(param1) == Number(param2)) return 0;
19 if(Number(param1) < Number(param2)) return -1;
20 }
21 } 對於上述代碼的具體解釋,請參考《數組排序以及在漢字排序中localeCompare()方法的使用》,
以上我們說明了單列表格的排序思路及方法,有了這些思路我們可以很容易的擴展我們的程序,實現具有更多功能的表格排序。