分享一个自己写的table表格排序js插件(高效简洁)


Posted in Javascript onOctober 29, 2011

像:jQuery的table排序插件(感觉其使用比较麻烦或不清楚其具体用法,就没有使用)、原生态js的table排序插件等,最后比较看了下——采用了一个原生态js的table排序插件,并在其基础上做了些修改,虽有些勉强或有些地方使用不太舒服,但最算是比较好的实现了当时需要的功能。而前两天,对原有表格做了点儿修改——增加隔行换色的功能,问题就出现了,——效果错乱;检查分析了下,问题出在其table排序插件代码上——其原代码写的比较难理解,修改还不如重新自己写一个table排序插件。

说写就写,table排序其实很简单:就是取出所有排序列的值并存放在数组中(并且各列对应行对象也存放到一个数组中),然后对排序列的值数组排序(并对行对象数组排序)。下面贴出table排序插件代码:

/** 
* @description 表格排序实现 
* @author Blog:http://www.cnblogs.com/know/ 
* @date 2011-10-28 
**/ 
(function () { 
//初始化配置对象 
var _initConfig = null; 
var _tableObj = null, _tbodyObj = null, _tBodyIndex = 0; 
//存放当前各排序方式下的(有序)行数组的对象——仅在IsLazyMode=true,此变量有用 
var _trJqObjArray_Obj = null; 
/** 
* 添加排序方式(规则)的方法 
* @private 
* @param trJqObjArr:(外部传入)存放排序行的数组,tdIndex:排序列的索引,td_valAttr:排序列的取值属性,td_dataType:排序列的值类型 
**/ 
function _GetOrderTdValueArray(trJqObjArr, tdIndex, td_valAttr, td_dataType) { 
var tdOrderValArr = new Array(); 
var trObj, tdObj, tdVal; 
_tbodyObj.find("tr").each(function (i, trItem) { 
trObj = $(trItem); 
trJqObjArr.push(trObj); 
tdObj = trObj.find("td")[tdIndex]; 
tdObj = $(tdObj); 
tdVal = td_valAttr ? tdObj.attr(td_valAttr) : tdObj.text(); 
tdVal = _GetValue(tdVal, td_dataType); 
tdOrderValArr.push(tdVal); 
}); 
return tdOrderValArr; 
} 
/** 
* 返回jQuery对象的方法 
* @private 
**/ 
function _GetJqObjById(id) { 
return "string" == typeof (id) ? $("#" + id) : $(id); 
}; 
/** 
* 排序方法 
* @private 
* @param tdIndex:排序列的索引,options:排序列的规则配置对象 
**/ 
function _Sort(tdIndex, options) { 
var trJqObjArr = null; 
if (_initConfig.IsLazyMode) { 
!_trJqObjArray_Obj && (_trJqObjArray_Obj = {}); 
trJqObjArr = _trJqObjArray_Obj[tdIndex]; 
} 
var isExist_trJqObjArr = true; 
if (!trJqObjArr) { 
isExist_trJqObjArr = false; 
trJqObjArr = new Array(); 
var tdOrderValArr = _GetOrderTdValueArray(trJqObjArr, tdIndex, options.ValAttr, options.DataType); 
var sort_len = tdOrderValArr.length - 1; 
var isExchanged = false, compareOper = options.Desc ? ">" : "<"; 
for (var i = 0; i < sort_len; i++) { 
isExchanged = false; 
for (var j = sort_len; j > i; j--) { 
if (eval(tdOrderValArr[j] + compareOper + tdOrderValArr[j - 1])) { 
_ExchangeArray(tdOrderValArr, j); 
//交换行对象在数组中的顺序 
_ExchangeArray(trJqObjArr, j); 
isExchanged = true; 
} 
} 
//一遍比较过后如果没有进行交换则退出循环 
if (!isExchanged) 
break; 
} 
_initConfig.IsLazyMode && (_trJqObjArray_Obj[tdIndex] = trJqObjArr); 
} 
if (trJqObjArr) { 
if (options.Toggle) { 
_initConfig.IsLazyMode && isExist_trJqObjArr && trJqObjArr.reverse(); 
options.Desc = !options.Desc; 
} 
_ShowTable(trJqObjArr); 
} 
} 
/** 
* 显示排序后的表格 
* @private 
* @param trJqObjArr:排序后的tr对象数组 
**/ 
function _ShowTable(trJqObjArr) { 
_tbodyObj.html(""); 
for (var n = 0, len = trJqObjArr.length; n < len; n++) { 
_tbodyObj.append(trJqObjArr[n]); 
$.isFunction(_initConfig.OnShow) && (_initConfig.OnShow(n, trJqObjArr[n], _tbodyObj)); 
} 
} 
/** 
* 交换数组中项的方法 
* @private 
* @param array:数组,j:交换数组项的尾项索引 
**/ 
function _ExchangeArray(array, j) { 
var temp = array[j]; 
array[j] = array[j - 1]; 
array[j - 1] = temp; 
} 
/** 
* 添加排序方式(规则)的方法 
* @private 
* @param tdVal:排序列的值,td_dataType:排序列的值类型 
**/ 
function _GetValue(tdVal, td_dataType) { 
switch (td_dataType) { 
case "int": 
return parseInt(tdVal) || 0; 
case "float": 
return parseFloat(tdVal) || 0; 
case "date": 
return Date.parse(tdVal) || 0; 
case "string": 
default: 
return tdVal.toString() || ""; 
} 
} 
/** 
* 添加排序方式(规则)的方法 
* @private 
* @param obj:排序触发(标签)的对象或id,index:要排序列所在的列索引,options:排序规则设置对象(如:DataType...) 
**/ 
function _SetOrder(obj, index, options) { 
var orderSettings = { 
ValAttr: false, //排序列的取值属性,默认为:innerText 
DataType: "string", //排序列的值类型(可取值:int|float|date|string) 
OnClick: null, //(点击)排序时触发的方法 
Desc: true, //(是否是降序)排序方式,默认为:降序 
Toggle: true, //切换排序方式 
DefaultOrder: false //是否是默认的排序方式 
}; 
$.extend(orderSettings, options); 
orderSettings.DataType = orderSettings.DataType.toLowerCase(); 
obj = _GetJqObjById(obj); 
//绑定触发排序的事件 
obj.bind("click", function () { 
_Sort(index, orderSettings); 
$.isFunction(orderSettings.OnClick) && orderSettings.OnClick(); 
}); 
orderSettings.DefaultOrder && _Sort(index, orderSettings); 
} 
var _api = { 
Init: function (obj, tBodyIndex, options) { 
if (obj == null || typeof (obj) == undefined) { 
alert("TableOrder初始化参数为空或有误!"); 
return; 
} 
_tableObj = _GetJqObjById(obj); 
_tBodyIndex = tBodyIndex || 0; 
_tbodyObj = _tableObj.find("tbody:eq(" + _tBodyIndex + ")"); 
options = options || {}; 
_initConfig = { 
IsLazyMode: true, //是否是懒惰模式,默认为:true 
OnShow: null //排序后表格显示时的方法,params:trIndex,trJqObj,tbodyObj 
}; 
$.extend(_initConfig, options); 
_trJqObjArray_Obj = null; 
}, 
SetOrder: function (obj, index, options) { 
if (_tableObj == null) { 
alert("_tableObj尚未初始化!"); 
return; 
} 
_SetOrder(obj, index, options); 
} 
}; 
window.TableOrderOper = _api; 
})();

其使用如下:
<table border="0" cellspacing="0" cellpadding="0" class="fu_list" id="idTable"> 
<thead> 
<tr> 
<td> <a href="javascript:void(0)" id="idTitle">名称</a> / <a href="javascript:void(0)" id="idExt">类型</a></td> 
<td width="150" align="center"><a href="javascript:void(0)" id="idAddtime" class="up">上传时间</a></td> 
<td width="50" align="center"><a href="javascript:void(0)" id="idSize">大小</a></td> 
</tr> 
</thead> 
<tbody> 
<tr class="hoverTr"> 
<td _ext="rar">JSCSS</td> 
<td align="center" _order="2008/9/12 8:51:09">2008/9/12 8:51:09</td> 
<td align="right" _order="433247">433247</td> 
</tr> 
<tr> 
<td _ext="htm">AJAX</td> 
<td align="center" _order="2008/3/6 20:12:23">2008/3/6 20:12:23</td> 
<td align="right" _order="11394">11394</td> 
</tr> 
<tr> 
<td _ext="htm">EXT</td> 
<td align="center" _order="2008/10/4 20:21:54">2008/10/4 20:21:54</td> 
<td align="right" _order="351">351</td> 
</tr> 
<tr> 
<td _ext="xml">Index</td> 
<td align="center" _order="2008/10/4 20:24:11">2008/10/4 20:24:11</td> 
<td align="right" _order="14074">14074</td> 
</tr> 
<tr> 
<td _ext="js">ORDER</td> 
<td align="center" _order="2008/10/4 20:24:11">2008/10/4 20:24:11</td> 
<td align="right" _order="2844">2844</td> 
</tr> 
</tbody> 
</table> 
<script src="../Scripts/jquery-1.4.1.min.js" type="text/javascript"></script> 
<script src="TableOrder.js" type="text/javascript"></script> 
<script type="text/javascript"> 
TableOrderOper.Init("idTable", 0, { 
OnShow: function (i, trJqObj, _tbodyObj) { 
trJqObj.attr("class", ((i +1) %2==0?"hoverTr" : "")); 
} 
}); 
TableOrderOper.SetOrder("idAddtime", 1, { ValAttr: "_order", DataType: "date" }); 
TableOrderOper.SetOrder("idSize", 2, { DataType: "int", DefaultOrder: true, OnClick: function () { 
alert("idSize"); 
} }); 
</script>

代码中注释我都尽量写的比较清楚了,需要补充说明的是:

1.js使用的是闭包,我强调代码要尽可能的简洁易懂。

2.IsLazyMode属性设置,IsLazyMode=true,适用于当前要排序的表格是不变的,即不会有ajax的增删改行的操作,而且你看代码后就可以看出的一个好处:把要排序列的对应的行对象只一次遍历,并将排序后的行对象数组保存在全局对象中,下次排序时直接通过tdIndex(排序列的索引)取出对应的行对象数组,并将数组反转,即可实现排序的效果,可以在一定程度上提高代码执行效率(性能); IsLazyMode=false, 即适用于当前要排序的表格会改变,如有ajax的增删改行的操作的情况。

3.考虑一般要排序的表格数据量都不大,其中的数组排序使用的是冒泡排序算法。

4.OnShow: null //排序后表格显示时的方法,params:trIndex,trJqObj,tbodyObj ——可方便用于设置排序后的表格的换行样式等,也出于对性能优化方面的考虑。

好了,最后,附上插件js和demo,目前的实现只能说是能很好的满足我当前项目中的需求或适用于于大多数的场景,如果有没有考虑到或不好的地方,希望各位路过的朋友,能毫不客气的拍砖留言,大家互相交流学习!

OrderTable.rar

原文地址: cnblogs know

Javascript 相关文章推荐
js全屏显示显示代码的三种方法
Nov 11 Javascript
JS中的异常处理方法分享
Dec 22 Javascript
jQuery实现的一个tab切换效果内部还嵌有切换
Aug 10 Javascript
常用的JavaScript WEB操作方法分享
Feb 28 Javascript
jquery滚动加载数据的方法
Mar 09 Javascript
jQuery基于$.ajax设置移动端click超时处理方法
May 14 Javascript
详解vuejs几种不同组件(页面)间传值的方式
Jun 01 Javascript
JavaScript实现简单的树形菜单效果
Jun 23 Javascript
Vue axios 中提交表单数据(含上传文件)
Jul 06 Javascript
深入理解Antd-Select组件的用法
Feb 25 Javascript
微信小程序实现比较功能的方法汇总(五种方法)
Mar 07 Javascript
JavaScript实现简单的图片切换功能(实例代码)
Apr 10 Javascript
Json2Template.js 基于jquery的插件 绑定JavaScript对象到Html模板中
Oct 29 #Javascript
基于jQuery的输入框在光标位置插入内容, 并选中
Oct 29 #Javascript
基于jquery的无限级联下拉框js插件
Oct 29 #Javascript
对setInterval在火狐和chrome切换标签产生奇怪的效果之探索,与解决方案!
Oct 29 #Javascript
仿猪八戒网左下角的文字滚动效果
Oct 28 #Javascript
js实现双向链表互联网机顶盒实战应用实现
Oct 28 #Javascript
js常用代码段收集
Oct 28 #Javascript
You might like
php无限级评论嵌套实现代码
2018/04/18 PHP
php实现简易计算器
2020/08/28 PHP
jQuery实现自定义事件的方法
2015/04/17 Javascript
基于jQuery实现的打字机效果
2017/01/16 Javascript
js控制一个按钮是否可点击(可使用)disabled的实例
2017/02/14 Javascript
微信小程序 在线支付功能的实现
2017/03/14 Javascript
Vue2.0使用过程常见的一些问题总结学习
2017/04/10 Javascript
AngularJS基于factory创建自定义服务的方法详解
2017/05/25 Javascript
使用Node.js搭建静态资源服务详细教程
2017/08/02 Javascript
通过button将form表单的数据提交到action层的实例
2017/09/08 Javascript
vue登录路由验证的实现
2017/12/13 Javascript
原生JS+HTML5实现跟随鼠标一起流动的粒子动画效果
2018/05/03 Javascript
JS字符串常用操作方法实例小结
2019/06/24 Javascript
微信小程序自定义弹窗实现详解(可通用)
2019/07/04 Javascript
vue项目中使用bpmn-自定义platter的示例代码
2020/05/11 Javascript
Vue路由切换页面不更新问题解决方案
2020/07/10 Javascript
Python自定义函数的创建、调用和函数的参数详解
2014/03/11 Python
Python元组操作实例分析【创建、赋值、更新、删除等】
2017/07/24 Python
python opencv设置摄像头分辨率以及各个参数的方法
2018/04/02 Python
Python Django 命名空间模式的实现
2019/08/09 Python
python 动态调用函数实例解析
2019/10/21 Python
django-利用session机制实现唯一登录的例子
2020/03/16 Python
Pycharm中安装Pygal并使用Pygal模拟掷骰子(推荐)
2020/04/08 Python
python使用re模块爬取豆瓣Top250电影
2020/10/20 Python
Python使用paramiko连接远程服务器执行Shell命令的实现
2021/03/04 Python
Chi Chi London官网:购买连衣裙和礼服
2020/10/25 全球购物
医学专业个人求职自荐信格式
2013/09/23 职场文书
珍珠鸟教学反思
2014/02/01 职场文书
新文化运动的基本口号
2014/06/21 职场文书
创新社会管理心得体会
2014/09/12 职场文书
2015年农村党员干部主题教育活动总结
2015/03/25 职场文书
总结会主持词
2015/07/02 职场文书
2016北大自主招生自荐信模板
2016/01/28 职场文书
老舍《猫》教学反思
2016/02/17 职场文书
MySQL pt-slave-restart工具的使用简介
2021/04/07 MySQL
MySQL数据库10秒内插入百万条数据的实现
2021/11/01 MySQL