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的跨域调用文件
Nov 19 Javascript
IE、FF、Chrome浏览器中的JS差异介绍
Aug 13 Javascript
juery框架写的弹窗效果适合新手
Nov 27 Javascript
IE下Ajax缓存问题的快速解决方法(get方式)
Jan 09 Javascript
js实现的简单radio背景颜色选择器代码
Aug 18 Javascript
Vue render渲染时间戳转时间,时间转时间戳及渲染进度条效果
Jul 27 Javascript
bootstrap table实现合并单元格效果
Dec 24 Javascript
uni-app微信小程序登录并使用vuex存储登录状态的思路详解
Nov 04 Javascript
js正则匹配多个全部数据问题
Dec 20 Javascript
vue+animation实现翻页动画
Jun 29 Javascript
利用promise及参数解构封装ajax请求的方法
Mar 24 Javascript
JavaScript实现班级抽签小程序
May 19 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调用MySQL的存储过程的实现代码
2008/08/12 PHP
PHP表单递交控件名称含有点号(.)会被转化为下划线(_)的处理方法
2013/01/06 PHP
详解Grunt插件之LiveReload实现页面自动刷新(两种方案)
2015/07/31 PHP
简单谈谈PHP中的trait
2017/02/25 PHP
yii2使用GridView实现数据全选及批量删除按钮示例
2017/03/01 PHP
PHP输出多个元素的排列或组合的方法
2017/03/14 PHP
phpStorm+XDebug+chrome 配置详解
2019/04/01 PHP
Avengerls vs KG BO3 第三场2.18
2021/03/10 DOTA
JS实现self的resend
2010/07/22 Javascript
jQuery下通过$.browser来判断浏览器.
2011/04/05 Javascript
跟我学习javascript的prototype原型和原型链
2015/11/18 Javascript
jQuery EasyUI中的日期控件DateBox修改方法
2016/11/09 Javascript
[原创]JS基于FileSaver.js插件实现文件保存功能示例
2016/12/08 Javascript
Node.js通过身份证号验证年龄、出生日期与性别方法示例
2017/03/09 Javascript
解决Vue.js 2.0 有时双向绑定img src属性失败的问题
2018/03/14 Javascript
react实现换肤功能的示例代码
2018/08/14 Javascript
node中使用log4js4.x版本记录日志的方法
2019/08/20 Javascript
python函数装饰器用法实例详解
2015/06/04 Python
Python 实现随机数详解及实例代码
2017/04/15 Python
Python实现简单http服务器
2018/04/12 Python
Python使用Selenium爬取淘宝异步加载的数据方法
2018/12/17 Python
python爬虫租房信息在地图上显示的方法
2019/05/13 Python
Python字符串的一些操作方法总结
2019/06/10 Python
Django实现将一个字典传到前端显示出来
2020/04/03 Python
python 实现控制鼠标键盘
2020/11/27 Python
Html5 Canvas实现图片标记、缩放、移动和保存历史状态功能 (附转换公式)
2020/03/18 HTML / CSS
HTML5+CSS设置浮动却没有动反而在中间且错行的问题
2020/05/26 HTML / CSS
英国家电直销:Appliances Direct
2016/09/22 全球购物
西铁城美国官方网站:Citizen Watch美国
2019/11/08 全球购物
Oracle里面常用的数据字典有哪些
2014/02/14 面试题
大学生入党思想汇报
2014/01/01 职场文书
人事主管岗位职责
2014/01/30 职场文书
个人借款担保书
2014/04/02 职场文书
2014年培训工作总结范文
2014/11/27 职场文书
2015年国庆放假通知范文
2015/08/18 职场文书
MySQL sql模式设置引起的问题
2022/05/15 MySQL