JavaScript Sort 表格排序

所属分类: 网络编程 / JavaScript 阅读数: 1446
收藏 0 赞 0 分享
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">图片排序&nbsp;<img id="col0" src="img/arrow_small_up.png" /> </td>
<td onclick="SortTable('MyTable',1,'int')" style="cursor:pointer">整数排序&nbsp;<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">日期排序&nbsp;<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>
更多精彩内容其他人还在看

js实现图片上传预览原理分析

这篇文章主要为大家详细介绍了js实现图片上传预览的原理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Angular限制input框输入金额(是小数的话只保留两位小数点)

最近做项目遇到这样的需求输入框要求输入金额,只能输入数字,可以是小数,必须保留小数点后两位。下面分为两部分代码给大家介绍实现代码,需要的的朋友参考下吧
收藏 0 赞 0 分享

详解vue-cli + webpack 多页面实例配置优化方法

本篇文章主要介绍了详解vue-cli + webpack 多页面实例配置优化方法,具有一定的参考价值,有兴趣的可以了解一下
收藏 0 赞 0 分享

详解React-Native解决键盘遮挡问题(Keyboard遮挡问题)

本篇文章主要介绍了React-Native解决键盘遮挡问题(Keyboard遮挡问题),具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

JavaScript反弹动画效果的实现代码

本文通过实例代码给大家介绍了js反弹动画效果的实现代码,需要的朋友参考下吧
收藏 0 赞 0 分享

解决vue2.x中数据渲染以及vuex缓存的问题

本篇文章主要介绍了vue2.x中请求之前数据显示以及vuex缓存的问题,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

jsonp跨域请求详解

这篇文章主要为大家详细介绍了jsonp跨域请求的相关资料,激活了所有接口支持浏览器跨域请求的封装,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

解决vue里碰到 $refs 的问题的方法

本篇文章主要介绍了解决vue里碰到 $refs 的问题的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

js自定义弹框插件的封装

这篇文章主要为大家详细介绍了js自定义弹框插件的简单封装,自己封装一个弹框插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

深入理解vue $refs的基本用法

本篇文章主要介绍了深入理解vue $refs的基本用法 ,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享
查看更多