JavaScript Sort 表格排序 |
本文标签:Sort,表格排序 1.你真的懂JavaScript里面的Sort方法吗? 2.你知道JavaScript中 localeCompare 方法的函数体吗? 3.表格排序 方法 要哪些参数? JavaScript中的sort方法直接就提供了排序的功能,不需要我们自己写个循环一个个的判断 。但其机制仍然是那样的, 复制代码 代码如下: window.onload=function(){ var MyArr=new Array("red","green","gray"); MyArr.sort(); alert(MyArr.toString()); } 输出的结果为 gray,green,red;那如果为整数呢? 复制代码 代码如下: window.onload=function(){ var MyArr=new Array(2,25,7); MyArr.sort(); alert(MyArr.toString()); } 如果你认为是 2,7,25 ;那么很高兴的说声 你错了,它的结果是 2,25,7,为什么呢?因为sort方法它是以字符串的ASCII来判断的,任何非字符串都将会先转换为字符串, 从而出现了上述情况 。那我要对整数排序怎么办呢?转换呗,很简单,但是假如有 Float,Date,等等呢?都一样,写个转换函数不就得了 。说了就得做 。 复制代码 代码如下: function convert(DataValue,DataType){ switch(DataType){ case "int": return parseInt(DataValue); case "float": return parseFloat(DataValue); case "date": return new Date(Date.parse(DataValue)); default: return DataValue.toString(); } } 一个很简单的转换方法就出来了,大家注意一下Date,因为它是对象,所以与基本类型不同,每次都会生成一个新的对象 。 Sort 方法可以有个参数为sortfunction, 先看个简单的排序方法 复制代码 代码如下: function compare_function(value1,value2){ if(value1<value2) return -1; else if(value1>value2) return 1; else return 0; } 其实 localeCompare 函数与其也差不多 。当 value1小于value2时,返回-1,即顺序排列,将value1<value2,返回1,即逆时排序 。 回到重点,要对表格排序,点击表格头部即可排序,那么必须要有一个方法,取之为SortTable,那要对表格的某一列排序,要具备哪些参数呢?首先要一个表格ID来确定哪个表格,其次要 确定要排序的是哪一列,最后每一列的数据不一定都是字符串,所以要一个数据类型的参数,也就是 SortTable(TableID,Col,DataType); 复制代码 代码如下: var DTable=document.getElementById(TableID); var DBody=DTable.tBodies[0]; var DataRows=DBody.rows; var MyArr=new Array; //将所有的行放入数组 for(var i=0;i<DataRows.length;i++){ MyArr[i]=DataRows[i]; } MyArr.sort(CustomCompare(Col,DataType)); //创建一个文档碎片,将所有的行都添加进去,相当于一个暂存架,目的是(如果直接加到document.body里面,会插入一行,就刷新一次,如果数据多了就会影响用户体验) //先将行全部放在暂存架里面,然后将暂存架里面的行 一起添加到document.body,这样表格只会刷新一次 。 //就像你去商店购物,要先将要买的物品(行)全部写在单子上(文档碎片),然后超市全部购买,而不会想到一样东西就去一次,那么 var frag=document.createDocumentFragment(); for(var i=0;i<MyArr.length;i++){ frag.appendChild(MyArr[i]); //将数组里的行全部添加到文档碎片中 } DBody.appendChild(frag);//将文档碎片中的行全部添加到 body中 这样就可以完成一个排序,那么其中有个 CustomCompare 函数,为自定义的一个排序方法来作为Sort方法的参数,它两个参数,一个为排序的列,一个为数据类型 。 函数体为 复制代码 代码如下: return function CompareTRs(TR1,TR2){ var value1,value2; value1=convert(TR1.cells[Col].firstChild.nodeValue,DataType); value2=convert(TR2.cells[Col].firstChild.nodeValue,DataType); if(value1 < value2) return -1; else if(value1 > value2) return 1; else return 0; }; 当然,能写成这样的形式要拜闭包所赐 。在sort方法中遍历数组中的每一项(每一项存储的都是table得每一行)并会将参数传入 CompareTRs(TR1,TR2)中,然后返回结果 。 其实这样就OK,但是如果要对图片排序怎么办? 图片是什么类型的?不知道,那我们取巧一下,就用图片的标题,或者alt属性,它们总可以是字符串吧 。给它们一个自定义属性 customvalue,然后一句它的值来排序 。只是在实现的时候 要判断是否含有此属性,那么就要对CompareTRs方法修改了 。 复制代码 代码如下: function CustomCompare(Col,DataType){ return function CompareTRs(TR1,TR2){ var value1,value2; //判断是不是有customvalue这个属性 if(TR1.cells[Col].getAttribute("customvalue")){ value1=convert(TR1.cells[Col].getAttribute("customvalue"),DataType); value2=convert(TR2.cells[Col].getAttribute("customvalue"),DataType); } else{ value1=convert(TR1.cells[Col].firstChild.nodeValue,DataType); value2=convert(TR2.cells[Col].firstChild.nodeValue,DataType); } if(value1 < value2) return -1; else if(value1 > value2) return 1; else return 0; }; } 对图片的排序也解决了 。那如果用户要多次排序,点好几次呢?我们是不是还要修改CompareTRs方法呢? 很明显是不需要的,JavaScript中有个 reverse()方法可以将数组中的每项都倒过来 。对SortTable方法的修改只需如此如此 复制代码 代码如下: function SortTable(TableID,Col,DataType){ var DTable=document.getElementById(TableID); var DBody=DTable.tBodies[0]; var DataRows=DBody.rows; var MyArr=new Array; for(var i=0;i<DataRows.length;i++){ MyArr[i]=DataRows[i]; } //判断上次排序的列和这次是否为同一列 if(DBody.CurrentCol==Col){ MyArr.reverse(); //将数组倒置 } else{ MyArr.sort(CustomCompare(Col,DataType)); } //创建一个文档碎片,将所有的行都添加进去,相当于一个暂存架,目的是(如果直接加到document.body里面,会插入一行,就刷新一次,如果数据多了就会影响用户体验) //先将行全部放在暂存架里面,然后将暂存架里面的行 一起添加到document.body,这样表格只会刷新一次 。 //就像你去商店购物,要先将要买的物品(行)全部写在单子上(文档碎片),然后超市全部购买,而不会想到一样东西就去一次,那么 var frag=document.createDocumentFragment(); for(var i=0;i<MyArr.length;i++){ frag.appendChild(MyArr[i]); //将数组里的行全部添加到文档碎片中 } DBody.appendChild(frag);//将文档碎片中的行全部添加到 body中 DBody.CurrentCol=Col; //记录下当前排序的列 } JavaScript中的大小写一定要注意,很容易出错的 。 以上代码测试成功,对日期的排序,效果如图 ![]() 所有代码: 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>表格排序</title> <script type="text/javascript"> var IsAsc=true; function SortTable(TableID,Col,DataType){ var imgSort=document.getElementById(col+Col); //判断是逆序还是顺序 if(IsAsc==true){ imgSort.src=img/arrow_small_down.png; } else{ imgSort.src=img/arrow_small_up.png; } IsAsc=!IsAsc; var DTable=document.getElementById(TableID); var DBody=DTable.tBodies[0]; var DataRows=DBody.rows; var MyArr=new Array; for(var i=0;i<DataRows.length;i++){ MyArr[i]=DataRows[i]; } //判断上次排序的列和这次是否为同一列 if(DBody.CurrentCol==Col){ MyArr.reverse(); //将数组倒置 } else{ MyArr.sort(CustomCompare(Col,DataType)); } //创建一个文档碎片,将所有的行都添加进去,相当于一个暂存架,目的是(如果直接加到document.body里面,会插入一行,就刷新一次,如果数据多了就会影响用户体验) //先将行全部放在暂存架里面,然后将暂存架里面的行 一起添加到document.body,这样表格只会刷新一次 。 //就像你去商店购物,要先将要买的物品(行)全部写在单子上(文档碎片),然后超市全部购买,而不会想到一样东西就去一次,那么 var frag=document.createDocumentFragment(); for(var i=0;i<MyArr.length;i++){ frag.appendChild(MyArr[i]); //将数组里的行全部添加到文档碎片中 } DBody.appendChild(frag);//将文档碎片中的行全部添加到 body中 DBody.CurrentCol=Col; //记录下当前排序的列 } function CustomCompare(Col,DataType){ return function CompareTRs(TR1,TR2){ var value1,value2; //判断是不是有customvalue这个属性 if(TR1.cells[Col].getAttribute("customvalue")){ value1=convert(TR1.cells[Col].getAttribute("customvalue"),DataType); value2=convert(TR2.cells[Col].getAttribute("customvalue"),DataType); } else{ value1=convert(TR1.cells[Col].firstChild.nodeValue,DataType); value2=convert(TR2.cells[Col].firstChild.nodeValue,DataType); } if(value1 < value2) return -1; else if(value1 > value2) return 1; else return 0; }; } function convert(DataValue,DataType){ switch(DataType){ case "int": return parseInt(DataValue); case "float": return parseFloat(DataValue); case "date": return new Date(Date.parse(DataValue)); default: return DataValue.toString(); } } </script> </head> <body> <div id="container"> <table border="1" id="MyTable"> <thead> <tr> <td onclick="SortTable(MyTable,0,string)" style="cursor:pointer">图片排序 <img id="col0" src="img/arrow_small_up.png" /> </td> <td onclick="SortTable(MyTable,1,int)" style="cursor:pointer">整数排序 <img id="col1" src="img/arrow_small_up.png" /></td> <td onclick="SortTable(MyTable,2,float)" style="cursor:pointer">浮点数排序<img id="col2" src="img/arrow_small_up.png" /></td> <td onclick="SortTable(MyTable,3,string)" style="cursor:pointer">字符串排序<img id="col3" src="img/arrow_small_up.png" /></td> <td onclick="SortTable(MyTable,4,date)" style="cursor:pointer">日期排序 <img id="col4" src="img/arrow_small_up.png" /></td> </tr> </thead> <tbody> <tr> <td customvalue="doc"> <img src="img/wordicon.gif" /></td> <td>2</td> <td>5.4</td> <td>zd</td> <td>2009-10-31 14:33:13</td> </tr> <tr> <td customvalue="zip"> <img src="img/zippedfoldericon.gif" /></td> <td>267</td> <td>8.9</td> <td>xx</td> <td>2002-10-31 14:36:13</td> </tr> <tr> <td customvalue="xlt"> <img src="img/excelicon.gif" /></td> <td>6</td> <td>60.4</td> <td>ty</td> <td>2009-10-31 19:33:13</td> </tr> <tr> <td customvalue="txt"> <img src="img/notepadicon.gif" /></td> <td>9</td> <td>0.8</td> <td>lp;</td> <td>2004-5-31 14:33:13</td> </tr> <tr> <td customvalue="doc"> <img src="img/wordicon.gif" /></td> <td>34</td> <td>9.4</td> <td>cv</td> <td>1009-10-31 14:33:13</td> </tr> <tr> <td customvalue="txt"> <img src="img/notepadicon.gif" /></td> <td>289</td> <td>23.4</td> <td>uio</td> <td>2005-10-31 14:33:13</td> </tr> <tr> <td customvalue="zip"> <img src="img/zippedfoldericon.gif" /></td> <td>45</td> <td>89.4</td> <td>cb</td> <td>1039-10-31 14:33:13</td> </tr> <tr> <td customvalue="doc"> <img src="img/wordicon.gif" /></td> <td>2</td> <td>5.4</td> <td>zd</td> <td>2009-10-31 14:33:13</td> </tr> <tr> <td customvalue="txt"> <img src="img/notepadicon.gif" /></td> <td>42</td> <td>9.3</td> <td>bm</td> <td>1069-10-31 14:34:14</td> </tr> </tbody> </table> </div> </body> </html> |