您的位置:首页 > Web前端 > JavaScript

javascript实现了客户端页面的表格排序

2009-05-23 21:58 691 查看
好久没写博了,一直以来都太忙了:进入到后半学期后,每周要上四次课,每天都要备课,有点时间就赶工,没时间写。尽管如此,刚刚解决的客户端页面用javascript实现的表格排序,还是要记录下来。 

需求背景:系统中的一个统计功能,速度较慢,按照之前的做法,是通过把结果表格的表头文字做成链接,向服务器提交排序的列名和排序方式(升序/降序),然后重新从服务端返回结果来实现的排序。但是,这种方法无疑效率很差,加重了网络通信和服务器的负担。于是考虑用javascript在客户端页面对结果列表排序。 

说实话,这种方法以前还真没接触过,上网查了一下,发现其实已经不是什么新鲜的办法了。能找到很多,我觉得cloudgamer做得很好(http://www.cnblogs.com/cloudgamer/archive/2008/10/06/1304414.html),实现了对包括复选框、单选框列在内的各种类型的table列排序。可惜的是,在我的项目中没有应用成功,不知道跟在rails中使用RJS有关。后来,又找到了利用javascript中的moveRows方法,移动table中的行的方法,而且有一个现成的代码可用。但是发现该代码只是将行的顺序颠倒,而不能对乱序的行真正排序。不过这个方法很有启发性。最终,结合在网上又找到的javascript实现的排序算法,自己最终实现了针对本项目的排序方法。 

代码如下: 

1、页面调用的排序函数。其中sorttype=1表示降序,-1表示升序;BubbleSort为冒泡排序法。

参数:nColNum为列序号(从0开始);strDataType为所排序的数据类型,如int、float等。

var sorttype = 1; //desc
function sortByCol(nColNum,strDataType){ //排序
var table = document.getElementById("tblResult"); //定位到table上
BubbleSort(table,nColNum,strDataType,sorttype);
sorttype = 0 - sorttype; //asc
}


 

2、冒泡排序函数。

参数:table为要排序的表格;nColNum为列序号(从0开始);strDataType为所排序的数据类型,如int、float等,函数中根据不同的数据类型,做相应的类型转换,再比较。

其它:函数主要就是根据传入的参数,对待排序表格(table)的指定列(nColNum),以某种数据类型(strDataType),按照指定排序方式(nSortOrder,升序/降序),以冒泡排序法排序。其中用类似“table.rows[j].cells[nColNum].childNodes[0].data”这样的语句,取得table中某一行某个单元格中的数据。交换两行时,调用Swap函数。本函数中对int、float类型的数据做了显式转换,根据具体需求,可继续扩充。

需要注意的另外一点,是for(var i=1;i<length;i++)这层循环:由于表格的第一行是列名(表头),故从i=1开始循环,而不是i=0。

function BubbleSort(table,nColNum,strDataType,nSortOrder){ //冒泡排序
var length=table.rows.length;
for(var i=1;i<length;i++){  //由于表头还有一行,故i从1开始
var exchanged=false;
for(var j=length-1;j>i;j--){
switch(strDataType){
case "int":
if(nSortOrder>0){  //desc
if(parseInt(table.rows[j].cells[nColNum].childNodes[0].data) >
parseInt(table.rows[j-1].cells[nColNum].childNodes[0].data)){
Swap(table,j,j-1);
exchanged=true;
}
}
else{
if(parseInt(table.rows[j].cells[nColNum].childNodes[0].data) <
parseInt(table.rows[j-1].cells[nColNum].childNodes[0].data)){
Swap(table,j,j-1);
exchanged=true;
}
}
break;
case "float":
if(nSortOrder>0){  //desc
if(parseFloat(table.rows[j].cells[nColNum].childNodes[0].data) >
parseFloat(table.rows[j-1].cells[nColNum].childNodes[0].data)){
Swap(table,j,j-1);
exchanged=true;
}
}
else{
if(parseFloat(table.rows[j].cells[nColNum].childNodes[0].data) <
parseFloat(table.rows[j-1].cells[nColNum].childNodes[0].data)){
Swap(table,j,j-1);
exchanged=true;
}
}
break;
case "string":
default:
if(nSortOrder>0){  //desc
if(table.rows[j].cells[nColNum].childNodes[0].data.toString() >
table.rows[j-1].cells[nColNum].childNodes[0].data.toString()){
Swap(table,j,j-1);
exchanged=true;
}
}
else{
if(table.rows[j].cells[nColNum].childNodes[0].data.toString() <
table.rows[j-1].cells[nColNum].childNodes[0].data.toString()){
Swap(table,j,j-1);
exchanged=true;
}
}
} //switch
} //for j
if (!exchanged) break;
} //for i
}


 

3、交换表格行的函数。

参数:table为要交换行的表格;i、j为要交换的两个行号。

这个函数就是充分利用了table元素的moveRow方法,实现两行位置的交换。该方法的第一个参数是待移动的行号,第二个参数是移动目标位置的行号。这个函数移动某行后,其它行的位置会做相应调整。根据i、j大小的不同,要想达到最终交换两行的目的,要分别做两种不同的操作,如函数中所写。这个过程很简单,在纸上画一画就能明白了。

function Swap(table,i,j){

if(i<0 || j>table.rows.length-1) return;
if(i<j){
table.moveRow(i,j);
table.moveRow(j-1,i);
}
else{
table.moveRow(i,j);
table.moveRow(j+1,i);
}
}


 

最后,在页面上只要把表格可排序的列名做成链接调用sortByCol函数即可,如:

<th nowrap>
   <a href="#" onclick="sortByCol(0);">学科代码</a>
</th>

根据BubbleSort函数中的switch,不指定数据类型(即第二个参数)的话,就是默认按照字符串类型排序。下面是指定了数据类型的:

<th nowrap>
    <a href="#" onclick="sortByCol(2,'float');">百分比(%)</a>
</th> 

再有就是,还可用快速排序等其它排序方法实现,相应算法网上也很容易找到,做相应改造即可。

由于实际应用中,结果未分页,故这三个函数也未实现对分页数据的排序。

这个方法的一般性还未仔细考察,留待以后用在其它页面上时再做。 

javascript很强大,还有很多可学的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息