本文所實(shí)現(xiàn)的表格排序大致可以分為以下幾個(gè)步驟:
1、取得要排序的所有行,將其引用push到一個(gè)數(shù)組中
2、根據(jù)要排序的行的情況編寫數(shù)組排序時(shí)使用的比較函數(shù)
3、對(duì)包含所有行引用的數(shù)組進(jìn)行排序
4、將排序后的數(shù)組按照指定的順序把數(shù)組所引用的行重新寫回DOM
如果您對(duì)使用DOM操作表格還不太熟悉,您可以參考一下
《使用DOM編寫瀏覽器兼容的Table操作》,如果您對(duì)數(shù)組的排序還不太熟悉,可以參考一下
《數(shù)組排序以及在漢字排序中l(wèi)ocaleCompare()方法的使用》,因?yàn)槭褂肈OM操作表格和數(shù)組排序是表格排序的基礎(chǔ)。
先看一下我們示例用的代碼,本文會(huì)按照上面提到的步驟一步一步的分析:
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 //將要排序的行放入數(shù)組以排序
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 = "點(diǎn)擊降序排列表格";
16 asc = false;
17 } else {
18 //如果是降序
19 arrayTr.reverse();
20 oTable.rows[0].title = "點(diǎn)擊升序排列表格";
21 asc = true;
22 }
23 //將排過續(xù)的行按照數(shù)序重寫回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行實(shí)現(xiàn)了我們所說的第一步,這里有兩個(gè)需要說明的地方,一是我們?cè)贖TML中使用了<thead/>和<tbody />標(biāo)簽用于分割表格的標(biāo)題本分以及要排序的部分,礙于篇幅HTML代碼不再展示,二是《JavaScript高級(jí)程序設(shè)計(jì)》說Table的 tBodies屬性是一個(gè)JS中的集合,而不是數(shù)組,沒有sort()方法,所以不能用來直接排序,關(guān)于JS集合的概念還需要我們好好研究啊,不過這不是本文的重點(diǎn),這里我們想說明的重點(diǎn)是,tBodies不能拿來直接排序。
程序的13--22行實(shí)現(xiàn)了第三步,這里我們隱藏了第二步的具體實(shí)現(xiàn)(在后面的部分會(huì)詳細(xì)說明)我們認(rèn)為這樣可以更好的說明我們的思路,而不會(huì)讓自己糾纏于具體的方法實(shí)現(xiàn)導(dǎo)致對(duì)程序沒有一個(gè)總體的認(rèn)識(shí)。還要說明的是程序中我們使用了一個(gè)全局性的容器來裝載排序行,所以函數(shù)執(zhí)行后,arrayTr總會(huì)包含最后一次排序的行引用順序,這時(shí)如果我們想進(jìn)行倒序的話只需調(diào)用reverse()方法,而不再需要對(duì)數(shù)組進(jìn)行逆向排序。
程序的24行使用了document.createDocumentFragment()可以得到一個(gè)文檔碎片,documentFragment是一個(gè)不完整的document對(duì)象,主要用于存放暫時(shí)沒有加入dom樹的Element。作為js操作dom的緩存,十分好用,他會(huì)一次性的將改動(dòng)在DOM中呈現(xiàn),而不是每次操作DOM都要是客戶端重繪。
下面看用于實(shí)現(xiàn)我們第二步的函數(shù)的具體實(shí)現(xiàn):
1 /**
2 * 比較函數(shù)
3 * @param {Object} param1 要比較的行1
4 * @param {Object} param2 要比較的行2
5 * @return {Number} 如果param1 > param2 返回 1
6 * 如果param1 == param2 返回 0
7 * 如果param1 < param2 返回 -1
8 */
9 function compareFunc(oTr1,oTr2){
10 var param1 = oTr1.cells[0].childNodes[0].nodeValue;
11 var param2 = oTr2.cells[0].childNodes[0].nodeValue;
12 //如果兩個(gè)參數(shù)均為字符串類型
13 if(isNaN(param1) && isNaN(param2)){
14 return param1.localeCompare(param2);
15 }
16 //如果參數(shù)1為數(shù)字,參數(shù)2為字符串
17 if(!isNaN(param1) && isNaN(param2)){
18 return -1;
19 }
20 //如果參數(shù)1為字符串,參數(shù)2為數(shù)字
21 if(isNaN(param1) && !isNaN(param2)){
22 return 1;
23 }
24 //如果兩個(gè)參數(shù)均為數(shù)字
25 if(!isNaN(param1) && !isNaN(param2)){
26 if(Number(param1) > Number(param2)) return 1;
27 if(Number(param1) == Number(param2)) return 0;
28 if(Number(param1) < Number(param2)) return -1;
29 }
30 }
對(duì)于上述代碼的具體解釋,請(qǐng)參考
《數(shù)組排序以及在漢字排序中l(wèi)ocaleCompare()方法的使用》,因?yàn)槲覀冎辉?0行、11行改變了取數(shù)據(jù)的方式而已。
以上我們說明了單列表格的排序思路及方法,有了這些思路我們可以很容易的擴(kuò)展我們的程序,實(shí)現(xiàn)具有更多功能的表格排序。
posted on 2008-07-21 17:00
零全零美 閱讀(1565)
評(píng)論(0) 編輯 收藏 所屬分類:
JavaScript