JavaScript Sort 表格排序


Posted in Javascript onOctober 31, 2009

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中的大小写一定要注意,很容易出错的。
以上代码测试成功,对日期的排序,效果如图
JavaScript Sort 表格排序
所有代码:
<!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>
Javascript 相关文章推荐
利用Jquery实现可多选的下拉框
Feb 21 Javascript
Javascript中With语句用法实例
May 14 Javascript
jQuery替换textarea中换行的方法
Jun 10 Javascript
javascript HTML5文件上传FileReader API
Mar 27 Javascript
ECMAScript6轮播图实践知识总结
Aug 17 Javascript
js点击任意区域弹出层消失实现代码
Dec 27 Javascript
在 Angular2 中实现自定义校验指令(确认密码)的方法
Jan 23 Javascript
JavaScript验证知识整理
Mar 24 Javascript
Express + Session 实现登录验证功能
Sep 08 Javascript
javascript 产生随机数的几种方法总结
Sep 26 Javascript
Vue2.0父子组件传递函数的教程详解
Oct 16 Javascript
vue实现图片加载完成前的loading组件方法
Feb 05 Javascript
DOM 脚本编程中的兄弟节点
Oct 31 #Javascript
javascript GUID生成器实现代码
Oct 31 #Javascript
json 实例详细说明教程
Oct 31 #Javascript
json 入门基础教程 推荐
Oct 31 #Javascript
jquery text()要注意啦
Oct 30 #Javascript
CCPry JS类库 代码
Oct 30 #Javascript
Iframe 自适应高度并实时监控高度变化的js代码
Oct 30 #Javascript
You might like
PHP 过滤页面中的BOM(实现代码)
2013/06/29 PHP
Drupal7连接多个数据库及常见问题解决
2014/03/02 PHP
如何使用纯PHP实现定时器任务(Timer)
2015/07/31 PHP
PHP getallheaders无法获取自定义头(headers)的问题
2016/03/23 PHP
js常用代码段收集
2011/10/28 Javascript
from 表单提交返回值用post或者是get方法实现
2013/08/21 Javascript
js中的异常处理try...catch使用介绍
2013/09/21 Javascript
JQuery弹出层示例可自定义
2014/05/19 Javascript
基于jQuery实现复选框的全选 全不选 反选功能
2014/11/24 Javascript
NodeJS制作爬虫全过程(续)
2014/12/22 NodeJs
jQuery中html()方法用法实例
2014/12/25 Javascript
js使用cookie记录用户名的方法
2015/11/26 Javascript
javascript创建对象、对象继承的实用方式详解
2016/03/08 Javascript
javascript简单实现深浅拷贝过程详解
2019/10/08 Javascript
javascript 原型与原型链的理解及实例分析
2019/11/23 Javascript
vue-property-decorator用法详解
2019/12/12 Javascript
vue-cli3配置favicon.ico和title的流程
2020/10/27 Javascript
wxPython框架类和面板类的使用实例
2014/09/28 Python
Python的面向对象思想分析
2015/01/14 Python
Python比较两个图片相似度的方法
2015/03/13 Python
Python中设置变量访问权限的方法
2015/04/27 Python
Python3.4编程实现简单抓取爬虫功能示例
2017/09/14 Python
Django的性能优化实现解析
2019/07/30 Python
tensorflow 保存模型和取出中间权重例子
2020/01/24 Python
哈萨克斯坦移动和数字技术在线商店:SatelOnline.kz
2020/09/04 全球购物
C有"按引用传递"吗
2016/09/06 面试题
舞蹈教育学专业推荐信
2013/11/27 职场文书
保安拾金不昧表扬信
2014/01/15 职场文书
教师党员承诺书
2014/03/25 职场文书
高中班主任评语大全
2014/04/25 职场文书
人力资源本科毕业生求职信
2014/06/04 职场文书
单位消防安全责任书
2014/07/23 职场文书
奥巴马上海演讲稿
2014/09/10 职场文书
2015年安全员工作总结范文
2015/04/22 职场文书
2019毕业典礼主持词!
2019/07/05 职场文书
Nginx利用Logrotate实现日志分割
2022/05/20 Servers