Javascript 在本機瀏覽器中對的表格數(shù)據(jù)進(jìn)行排序[轉(zhuǎn)]
當(dāng)前位置:點晴教程→知識管理交流
→『 技術(shù)文檔交流 』
在Web應(yīng)用中,數(shù)據(jù)從服務(wù)器端返回到客戶端,以表格形式表現(xiàn)出來。如果要對數(shù)據(jù)集按指定的列排序顯示,常規(guī)做法都是向服務(wù)器發(fā)出請求,服務(wù)器端程序重新從數(shù)據(jù)庫中取出按指定列排序的數(shù)據(jù),返回給客戶端,頁面重新顯示排序后數(shù)據(jù)。 采用這種方式有如下缺點: 1- 響應(yīng)時間延遲,每次排序都要向服務(wù)器端發(fā)送請求,等待結(jié)果返回,同時增加網(wǎng)絡(luò)負(fù)載。 2- 編程復(fù)雜,可維護(hù)性差,而且客戶端和服務(wù)器端代碼耦合度很高,客戶端和服務(wù)器端都要處理排序涉及的列名、排序方式,如果有分頁和查詢條件,都需要在客戶端頁面中保留,排序請求時重新傳遞到服務(wù)器端,當(dāng)參數(shù)數(shù)量很多時極易出錯。 3- 重用度很低,針對不同表格,很難抽象出一個公共程序來共用,需要逐個編寫代碼實現(xiàn),增加工作量。 現(xiàn)在換一個角度考慮,數(shù)據(jù)既然已下載到了客戶端,在重新排序時沒有必要再重服務(wù)器端獲取,只要對瀏覽器中的數(shù)據(jù)重新排序顯示就可以了。要實現(xiàn)該目標(biāo),需要做到以下幾點: 1 - 獲得表格中要排序的數(shù)據(jù),將其放入一個2維數(shù)組中。 2 - 對2維數(shù)組排序。 3 - 用排序后的數(shù)據(jù)重新更新表格。 利用瀏覽器支持的DOM(Document Object Model)和JavaScript即可實現(xiàn)上述目標(biāo)。 通常頁面中會很多的<table>,要獲得需要排序數(shù)據(jù)所在的table,需要在<table>中增加一個id屬性,便于document對象用getElementById得到該表格對象,例如要排序的表格定義如下: <table id="st" > <tr> <td>1</td> <td>2</td> </tr> </table> 在javascript中,用var objTable = document.getElementById("st")就可得到表格對象,該對象在DOM中定義為一個Element。 然后用 var objRows = objTable.getElementsByTagName("tr")得到該表格中全部的行對象,ObjRows.length返回該表格行數(shù);var rowi = objRows[i].getElementsByTagName("td")得到第i行的全部<td>節(jié)點,i從0開始計數(shù),rowi.item(j)則可得到第i行,第j列的節(jié)點,該節(jié)點的innerHTML為該節(jié)點<td></td>之間的內(nèi)容。 獲取表格數(shù)據(jù)到2維數(shù)組的代碼見源代碼,此處略。 下面說明在javascript中2維數(shù)組的構(gòu)造和排序。 javascript不支持2維數(shù)組,因此需要用數(shù)組的數(shù)組來模擬一個2維數(shù)組,其方法是先定義一個1維數(shù)組,元素個數(shù)為2維數(shù)組的行數(shù),然后對每個元素賦一個值,值為一個數(shù)組,其元素個數(shù)為2維數(shù)組的列數(shù)。構(gòu)造代碼如下: var rows = new Array(R); //R為行數(shù) for(var i = 0; i < rows.length; i++){ rows[i] = new Array(C); //C為列數(shù) } 利用javascript中的Array.sort(comparer)對rows中的元素排序,比較方式由重新定義的比較函數(shù)得到。要根據(jù)第j列元素的大小排序,只要定義如下函數(shù)即可: function compareCol(a,b){ if (a[j] < b[j]) return -1; if (a[j] > b[j]) return 1; return 0; } 因為compareCol只能有兩個參數(shù),因此j要定義為全局變量。 用rows.sort(compareCol)就可實現(xiàn)根據(jù)j列值的大小對行進(jìn)行排序。根據(jù)javascript文檔,字符串比較大小是按照其Unicode編碼的大小來比較,對英文排序沒有問題,對中文排序時就不是按通常的拼音排序,那需要javascript提供本地化支持,目前沒有發(fā)現(xiàn)javascript此功能。該功能在java中可用java.text.Collator實現(xiàn)。 以上介紹了在本地對瀏覽器中的數(shù)據(jù)進(jìn)行排序的主要思想,為方便使用,將這些功能進(jìn)行了封裝,以javascript函數(shù)的提供,存放在sorttable.js文件中,在需要的頁面中用<script type=text/javascript src='sorttable.js'></script>引入。 下面說明排序函數(shù)原型和使用方法。 函數(shù)1 function sortTable(tableId,sortCol,compareType)
函數(shù)2 function sortTableInRange(tableId,sortCol,compareType,startRow,endRow,startCol,endCol) 對表格中指定的區(qū)域數(shù)據(jù)排序,有時數(shù)據(jù)第一列為流水號,最后一行為合計,這些數(shù)據(jù)不需要參與排序,可用此函數(shù)來對部分?jǐn)?shù)據(jù)排序。 tableId 為<table id=''>中id的值,在同一個頁面中要唯一。 sortCol 排序時用來比較大小的數(shù)據(jù)所在的列,從1開始計數(shù)。 compareType 排序時比較大小的方式,s-按字符串比較大小,n-按數(shù)字比較大小。 startRow,endRow 要排序區(qū)域開始和結(jié)束行號,從1開始計數(shù)。例如對第2行到第7行排序,startRow=2,endRow=7 startCol,endCol 要排序區(qū)域開始和結(jié)束列號,從1開始計數(shù)。 存在的問題: 1- 中文不能按拼音排序。 要注意的問題: 要排序的table必須用ID標(biāo)示,并要作為參數(shù)傳給排序函數(shù),表格中的數(shù)據(jù)應(yīng)該是可以排序的,否則結(jié)果不可預(yù)知;要排序的表格不能有嵌套表,否則排序出錯。 本函數(shù)已在IE6.0 ,FireFox1.01中運行通過。源代碼和例子代碼見后。 參考資料: Danny Goodman with Michael Morrison JavaScript Bible 5th ,John Wiley and Sons 2004 David Flanagan JavaScript The Definitive Guide 4th , O'Reilly 2001 附源代碼:要運行例子,需要將javascript代碼保存到sorttable.js文件中,html部分代碼保存到同一目錄下另一文件中即可。 sorttable.js //========================================================= // // 在本機對瀏覽器頁面表格中的數(shù)據(jù)行進(jìn)行排序的javascript函數(shù) // // author William QQ: 22967225 // create date 2005-12-2 // version 1.0 //========================================================= //column index for sort var indexCol; //比較函數(shù),用于Array.sort()排序時比較用。 //本函數(shù)比較數(shù)組元素array1[indexCol]和元素array2[indexCol]Unicode值的大小 function arrayCompare(array1,array2){ //alert(array1.length+"--"+array1[indexCol]); if (array1[indexCol] < array2[indexCol]) return -1; if (array1[indexCol] > array2[indexCol]) return 1; return 0; } //比較數(shù)組元素array1[indexCol]和元素array2[indexCol]的數(shù)值大小 function arrayCompareNumber(array1,array2){ if (parseInt(array1[indexCol]) < parseInt(array2[indexCol])) return -1; if (parseInt(array1[indexCol]) > parseInt(array2[indexCol])) return 1; return 0; } //與arrayCompare相反方式比較大小,用于倒序使用 function arrayCompareRev(array1,array2){ if (array1[indexCol] < array2[indexCol]) return 1; if (array1[indexCol] > array2[indexCol]) return -1; return 0; } //與arrayCompareNumber相反方式比較大小,用于倒序使用 function arrayCompareNumberRev(array1,array2){ if (parseInt(array1[indexCol]) < parseInt(array2[indexCol])) return 1; if (parseInt(array1[indexCol]) > parseInt(array2[indexCol])) return -1; return 0; } //define a 2-dimension array function BiArray(rows,cols){ //simulate multidimension array this.rows = rows; this.cols = cols; //construct array var lines = new Array(rows); for(var i = 0;i < lines.length; i++){ lines[i] = new Array(cols); } // 設(shè)置數(shù)組在(i,j)的元素值為value this.setElement = function(i,j,value){ lines[i][j] = value; }; // 獲取數(shù)組在(i,j)處元素的值 this.getElement = function(i,j){return lines[i][j];}; // 返回數(shù)組第i行所在的數(shù)組 this.getLine = function(i){return lines[i];}; // 根據(jù)第j列字符串的值,對數(shù)組的行進(jìn)行排序,排序結(jié)果為升序 this.sortLine = function(j){ indexCol = j; lines.sort(arrayCompare); }; // 根據(jù)第j列數(shù)值的值,對數(shù)組的行進(jìn)行排序,排序結(jié)果為升序 this.sortLineByNumber = function(j){ indexCol = j; lines.sort(arrayCompareNumber); }; // 根據(jù)第j列字符串的值,對數(shù)組的行進(jìn)行排序,排序結(jié)果為倒序 this.sortLineRev = function(j){ indexCol = j; lines.sort(arrayCompareRev); }; // 根據(jù)第j列數(shù)值的值,對數(shù)組的行進(jìn)行排序,排序結(jié)果為倒序 this.sortLineByNumberRev = function(j){ indexCol = j; lines.sort(arrayCompareNumberRev); }; //將二維數(shù)組轉(zhuǎn)為字符串格式 this.toString = function(){ var rst =""; for(var i = 0; i < lines.length; i++){ for(var j = 0; j < lines[i].length; j++){ rst += lines[i][j]; rst += '\t'; } rst += '\n'; } return rst; }; } // end of BiArray define //ascending or descending var asce = true; /** 對表格中指定范圍的數(shù)據(jù)進(jìn)行排序 tableId 要排序的表格的id,值格式為 <table id="tb1" > sortCol 用于排序的列號,從1開始計數(shù) compareType 排序時比較方式,s-按字符串比較,n-按數(shù)值比較 startRow 排序范圍起始行號,從1開始計數(shù) endRow 排序范圍結(jié)束行號,從1開始計數(shù) startCol 排序范圍起始列號,從1開始計數(shù) endCol 排序范圍結(jié)束列號,從1開始計數(shù) */ function sortTableInRange(tableId,sortCol,compareType,startRow,endRow,startCol,endCol){ try{ var table = document.getElementById(tableId); // get all row object of the table var objRows = table.getElementsByTagName("tr"); //alert(objRows.length); endRow = (endRow < objRows.length ? endRow : objRows.length); var sortRows = endRow - startRow + 1; //alert("sortRows "+sortRows); if (sortRows < 2) //only one line,don't sort return ; endCol = (endCol < objRows[1].getElementsByTagName("td").length ? endCol : objRows[1].getElementsByTagName("td").length); // column number of sort //var cols = objRows[1].childNodes.length; var cols = endCol - startCol + 1; // define a array to store table cell and sort them var tabData = new BiArray(sortRows,cols); var ari = 0; // retrived table cell data save to array for(i = startRow - 1; i < endRow; i++){ //retrived all <td> cell var cells = objRows[i].getElementsByTagName("td"); var arj = 0; for(var j = startCol - 1; j < endCol; j++){ tabData.setElement(ari,arj,cells.item(j).innerHTML); arj++; } ari++; } if (asce){ if (compareType == "n" || compareType == 'N') tabData.sortLineByNumber(sortCol- startCol); else tabData.sortLine(sortCol - startCol); asce = false; }else{ if (compareType == "n" || compareType == 'N') tabData.sortLineByNumberRev(sortCol - startCol); else tabData.sortLineRev(sortCol - startCol); asce = true; } ari = 0; //update table data with array for(i = startRow -1; i < endRow; i++){ //retrived all <td> cell var cells = objRows[i].getElementsByTagName("td"); arj = 0; for(var j = startCol - 1; j < endCol; j++){ cells.item(j).innerHTML = tabData.getElement(ari,arj); arj++; } ari++; } }catch(e){ alert(e); } } /** 對表格除第一行外的數(shù)據(jù)行排序,是sortYableInRange(tableId,sortCol,compareType,2,tabRows,1,tabCols) 的特例。 tableId 要排序的表格的id,值格式為 <table id="tb1" > 用于排序的列號,從1開始計數(shù) compareType 排序時比較方式,s-按字符串比較,n-按數(shù)值比較 */ function sortTable(tableId,sortCol,compareType){ try{ var table = document.getElementById(tableId); // get all row object of the table var objRows = table.getElementsByTagName("tr"); //alert(objRows.length); var endRows = objRows.length; if (endRows < 2) //only one line,don't sort return ; // column number of table var cols = objRows[1].getElementsByTagName("td").length; sortTableInRange(tableId,sortCol,compareType,2,endRows,1,cols); }catch(e){ alert(e); } } ==========javascript 代碼結(jié)束============ 例子HTML頁面代碼 <html> <head content="text/html; charset=gb2312" > <script type="text/javascript" src="sorttable.js"> </script> </head> <body> 常規(guī)排序例子<br> <table id="t1" border="1"> <tr> <td width="20%"><a href="#" onclick="sortTable('t1',1,'s')" >城市</a></td> <td width="30%"><a href="#" onclick="sortTable('t1',2,'s')" >品牌</a></td> <td width="30%"><a href="#" onclick="sortTable('t1',3,'n')" >銷量</a></td> </tr> <tr> <td><a href="#" >北京</a></td> <td>GOOGLE</td> <td>64</td> </tr> <tr> <td>上海</td> <td>CISCO</td> <td>54</td> </tr> <tr> <td>廣州</td> <td>MS</td> <td>9</td> </tr> <tr> <td>南京</td> <td>INTEL</td> <td>120</td> </tr> </table> <br>對部分?jǐn)?shù)據(jù)排序例子(對第2-5行,第2-4列區(qū)域排序)<br> <table id="t2" border="1"> <tr> <td>序號</td> <td width="20%"><a href="#" onclick="sortTableInRange('t2',2,'s',2,5,2,4)" >城市</a></td> <td width="30%"><a href="#" onclick="sortTableInRange('t2',3,'s',2,5,2,4)" >品牌</a></td> <td width="30%"><a href="#" onclick="sortTableInRange('t2',4,'n',2,5,2,4)" >銷量</a></td> </tr> <tr> <td>1</td> <td><a href="#" >北京</a></td> <td>GOOGLE</td> <td>64</td> </tr> <tr> <td>2</td> <td>上海</td> <td>CISCO</td> <td>54</td> </tr> <tr> <td>3</td> <td>廣州</td> <td>MS</td> <td>9</td> </tr> <tr> <td>4</td> <td>南京</td> <td>INTEL</td> <td>120</td> </tr> </table> </body> </html> 該文章在 2010/8/18 0:58:43 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |