基于原生JS与jQuery的轻量级表格排序插件实现

作者:拾光

时间:2026-10-27

浏览:214

本文介绍了一个基于原生JavaScript和jQuery开发的轻量级表格排序插件。该插件支持整数、浮点数、日期和字符串等多种数据类型的排序,通过配置IsLazyMode属性优化性能,并支持隔行换色等自定义显示效果。文章提供了完整的插件源码、HTML结构示例及初始化配置方法,旨在为开发者提供高效简洁的表格排序解决方案。

文章目录

插件背景与开发动机

在之前的项目中,作者曾尝试使用jQuery的表格排序插件以及原生态JavaScript编写的排序插件。由于前者使用较为繁琐且文档不够清晰,后者虽然基础但功能有限,最终作者选择了一个原生态JavaScript的表格排序插件作为基础,并在此基础上进行了修改。尽管该方案在某些使用场景下略显勉强或不够舒适,但它较好地满足了当时的功能需求。然而,前两天对表格进行了修改,增加了隔行换色的功能,结果导致了效果错乱。经过检查和分析,发现问题的根源在于原有表格排序插件的代码逻辑较为晦涩难懂,修改起来比重新编写一个插件还要困难。因此,作者决定重新编写一个表格排序插件。



核心逻辑与代码实现

说做就做,表格排序的核心逻辑其实并不复杂:主要步骤是提取所有需要排序的列的值,并将它们存储在数组中;同时,将对应的行对象也存储到另一个数组中。接着,对存储排序列值的数组进行排序,并同步调整行对象数组的顺序。以下是表格排序插件的具体代码实现:


代码如下:

 
/** 
* @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

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章