分享一個(gè)自己寫的table表格排序js插件(高效簡(jiǎn)潔)
更新時(shí)間:2011年10月29日 19:08:56 作者:
在前不久做的一個(gè)web項(xiàng)目中,需要實(shí)現(xiàn)js表格排序的效果,當(dāng)時(shí)為了省事,就在網(wǎng)上找了幾個(gè)相關(guān)的js插件
像:jQuery的table排序插件(感覺(jué)其使用比較麻煩或不清楚其具體用法,就沒(méi)有使用)、原生態(tài)js的table排序插件等,最后比較看了下——采用了一個(gè)原生態(tài)js的table排序插件,并在其基礎(chǔ)上做了些修改,雖有些勉強(qiáng)或有些地方使用不太舒服,但最算是比較好的實(shí)現(xiàn)了當(dāng)時(shí)需要的功能。而前兩天,對(duì)原有表格做了點(diǎn)兒修改——增加隔行換色的功能,問(wèn)題就出現(xiàn)了,——效果錯(cuò)亂;檢查分析了下,問(wèn)題出在其table排序插件代碼上——其原代碼寫的比較難理解,修改還不如重新自己寫一個(gè)table排序插件。
說(shuō)寫就寫,table排序其實(shí)很簡(jiǎn)單:就是取出所有排序列的值并存放在數(shù)組中(并且各列對(duì)應(yīng)行對(duì)象也存放到一個(gè)數(shù)組中),然后對(duì)排序列的值數(shù)組排序(并對(duì)行對(duì)象數(shù)組排序)。下面貼出table排序插件代碼:
/**
* @description 表格排序?qū)崿F(xiàn)
* @author Blog:http://www.cnblogs.com/know/
* @date 2011-10-28
**/
(function () {
//初始化配置對(duì)象
var _initConfig = null;
var _tableObj = null, _tbodyObj = null, _tBodyIndex = 0;
//存放當(dāng)前各排序方式下的(有序)行數(shù)組的對(duì)象——僅在IsLazyMode=true,此變量有用
var _trJqObjArray_Obj = null;
/**
* 添加排序方式(規(guī)則)的方法
* @private
* @param trJqObjArr:(外部傳入)存放排序行的數(shù)組,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對(duì)象的方法
* @private
**/
function _GetJqObjById(id) {
return "string" == typeof (id) ? $("#" + id) : $(id);
};
/**
* 排序方法
* @private
* @param tdIndex:排序列的索引,options:排序列的規(guī)則配置對(duì)象
**/
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);
//交換行對(duì)象在數(shù)組中的順序
_ExchangeArray(trJqObjArr, j);
isExchanged = true;
}
}
//一遍比較過(guò)后如果沒(méi)有進(jìn)行交換則退出循環(huán)
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對(duì)象數(shù)組
**/
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));
}
}
/**
* 交換數(shù)組中項(xiàng)的方法
* @private
* @param array:數(shù)組,j:交換數(shù)組項(xiàng)的尾項(xiàng)索引
**/
function _ExchangeArray(array, j) {
var temp = array[j];
array[j] = array[j - 1];
array[j - 1] = temp;
}
/**
* 添加排序方式(規(guī)則)的方法
* @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() || "";
}
}
/**
* 添加排序方式(規(guī)則)的方法
* @private
* @param obj:排序觸發(fā)(標(biāo)簽)的對(duì)象或id,index:要排序列所在的列索引,options:排序規(guī)則設(shè)置對(duì)象(如:DataType...)
**/
function _SetOrder(obj, index, options) {
var orderSettings = {
ValAttr: false, //排序列的取值屬性,默認(rèn)為:innerText
DataType: "string", //排序列的值類型(可取值:int|float|date|string)
OnClick: null, //(點(diǎn)擊)排序時(shí)觸發(fā)的方法
Desc: true, //(是否是降序)排序方式,默認(rèn)為:降序
Toggle: true, //切換排序方式
DefaultOrder: false //是否是默認(rèn)的排序方式
};
$.extend(orderSettings, options);
orderSettings.DataType = orderSettings.DataType.toLowerCase();
obj = _GetJqObjById(obj);
//綁定觸發(fā)排序的事件
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初始化參數(shù)為空或有誤!");
return;
}
_tableObj = _GetJqObjById(obj);
_tBodyIndex = tBodyIndex || 0;
_tbodyObj = _tableObj.find("tbody:eq(" + _tBodyIndex + ")");
options = options || {};
_initConfig = {
IsLazyMode: true, //是否是懶惰模式,默認(rèn)為:true
OnShow: null //排序后表格顯示時(shí)的方法,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">上傳時(shí)間</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>
代碼中注釋我都盡量寫的比較清楚了,需要補(bǔ)充說(shuō)明的是:
1.js使用的是閉包,我強(qiáng)調(diào)代碼要盡可能的簡(jiǎn)潔易懂。
2.IsLazyMode屬性設(shè)置,IsLazyMode=true,適用于當(dāng)前要排序的表格是不變的,即不會(huì)有ajax的增刪改行的操作,而且你看代碼后就可以看出的一個(gè)好處:把要排序列的對(duì)應(yīng)的行對(duì)象只一次遍歷,并將排序后的行對(duì)象數(shù)組保存在全局對(duì)象中,下次排序時(shí)直接通過(guò)tdIndex(排序列的索引)取出對(duì)應(yīng)的行對(duì)象數(shù)組,并將數(shù)組反轉(zhuǎn),即可實(shí)現(xiàn)排序的效果,可以在一定程度上提高代碼執(zhí)行效率(性能); IsLazyMode=false, 即適用于當(dāng)前要排序的表格會(huì)改變,如有ajax的增刪改行的操作的情況。
3.考慮一般要排序的表格數(shù)據(jù)量都不大,其中的數(shù)組排序使用的是冒泡排序算法。
4.OnShow: null //排序后表格顯示時(shí)的方法,params:trIndex,trJqObj,tbodyObj ——可方便用于設(shè)置排序后的表格的換行樣式等,也出于對(duì)性能優(yōu)化方面的考慮。
好了,最后,附上插件js和demo,目前的實(shí)現(xiàn)只能說(shuō)是能很好的滿足我當(dāng)前項(xiàng)目中的需求或適用于于大多數(shù)的場(chǎng)景,如果有沒(méi)有考慮到或不好的地方,希望各位路過(guò)的朋友,能毫不客氣的拍磚留言,大家互相交流學(xué)習(xí)!
OrderTable.rar
原文地址: cnblogs know
說(shuō)寫就寫,table排序其實(shí)很簡(jiǎn)單:就是取出所有排序列的值并存放在數(shù)組中(并且各列對(duì)應(yīng)行對(duì)象也存放到一個(gè)數(shù)組中),然后對(duì)排序列的值數(shù)組排序(并對(duì)行對(duì)象數(shù)組排序)。下面貼出table排序插件代碼:
復(fù)制代碼 代碼如下:
/**
* @description 表格排序?qū)崿F(xiàn)
* @author Blog:http://www.cnblogs.com/know/
* @date 2011-10-28
**/
(function () {
//初始化配置對(duì)象
var _initConfig = null;
var _tableObj = null, _tbodyObj = null, _tBodyIndex = 0;
//存放當(dāng)前各排序方式下的(有序)行數(shù)組的對(duì)象——僅在IsLazyMode=true,此變量有用
var _trJqObjArray_Obj = null;
/**
* 添加排序方式(規(guī)則)的方法
* @private
* @param trJqObjArr:(外部傳入)存放排序行的數(shù)組,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對(duì)象的方法
* @private
**/
function _GetJqObjById(id) {
return "string" == typeof (id) ? $("#" + id) : $(id);
};
/**
* 排序方法
* @private
* @param tdIndex:排序列的索引,options:排序列的規(guī)則配置對(duì)象
**/
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);
//交換行對(duì)象在數(shù)組中的順序
_ExchangeArray(trJqObjArr, j);
isExchanged = true;
}
}
//一遍比較過(guò)后如果沒(méi)有進(jìn)行交換則退出循環(huán)
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對(duì)象數(shù)組
**/
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));
}
}
/**
* 交換數(shù)組中項(xiàng)的方法
* @private
* @param array:數(shù)組,j:交換數(shù)組項(xiàng)的尾項(xiàng)索引
**/
function _ExchangeArray(array, j) {
var temp = array[j];
array[j] = array[j - 1];
array[j - 1] = temp;
}
/**
* 添加排序方式(規(guī)則)的方法
* @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() || "";
}
}
/**
* 添加排序方式(規(guī)則)的方法
* @private
* @param obj:排序觸發(fā)(標(biāo)簽)的對(duì)象或id,index:要排序列所在的列索引,options:排序規(guī)則設(shè)置對(duì)象(如:DataType...)
**/
function _SetOrder(obj, index, options) {
var orderSettings = {
ValAttr: false, //排序列的取值屬性,默認(rèn)為:innerText
DataType: "string", //排序列的值類型(可取值:int|float|date|string)
OnClick: null, //(點(diǎn)擊)排序時(shí)觸發(fā)的方法
Desc: true, //(是否是降序)排序方式,默認(rèn)為:降序
Toggle: true, //切換排序方式
DefaultOrder: false //是否是默認(rèn)的排序方式
};
$.extend(orderSettings, options);
orderSettings.DataType = orderSettings.DataType.toLowerCase();
obj = _GetJqObjById(obj);
//綁定觸發(fā)排序的事件
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初始化參數(shù)為空或有誤!");
return;
}
_tableObj = _GetJqObjById(obj);
_tBodyIndex = tBodyIndex || 0;
_tbodyObj = _tableObj.find("tbody:eq(" + _tBodyIndex + ")");
options = options || {};
_initConfig = {
IsLazyMode: true, //是否是懶惰模式,默認(rèn)為:true
OnShow: null //排序后表格顯示時(shí)的方法,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;
})();
其使用如下:
復(fù)制代碼 代碼如下:
<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">上傳時(shí)間</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>
代碼中注釋我都盡量寫的比較清楚了,需要補(bǔ)充說(shuō)明的是:
1.js使用的是閉包,我強(qiáng)調(diào)代碼要盡可能的簡(jiǎn)潔易懂。
2.IsLazyMode屬性設(shè)置,IsLazyMode=true,適用于當(dāng)前要排序的表格是不變的,即不會(huì)有ajax的增刪改行的操作,而且你看代碼后就可以看出的一個(gè)好處:把要排序列的對(duì)應(yīng)的行對(duì)象只一次遍歷,并將排序后的行對(duì)象數(shù)組保存在全局對(duì)象中,下次排序時(shí)直接通過(guò)tdIndex(排序列的索引)取出對(duì)應(yīng)的行對(duì)象數(shù)組,并將數(shù)組反轉(zhuǎn),即可實(shí)現(xiàn)排序的效果,可以在一定程度上提高代碼執(zhí)行效率(性能); IsLazyMode=false, 即適用于當(dāng)前要排序的表格會(huì)改變,如有ajax的增刪改行的操作的情況。
3.考慮一般要排序的表格數(shù)據(jù)量都不大,其中的數(shù)組排序使用的是冒泡排序算法。
4.OnShow: null //排序后表格顯示時(shí)的方法,params:trIndex,trJqObj,tbodyObj ——可方便用于設(shè)置排序后的表格的換行樣式等,也出于對(duì)性能優(yōu)化方面的考慮。
好了,最后,附上插件js和demo,目前的實(shí)現(xiàn)只能說(shuō)是能很好的滿足我當(dāng)前項(xiàng)目中的需求或適用于于大多數(shù)的場(chǎng)景,如果有沒(méi)有考慮到或不好的地方,希望各位路過(guò)的朋友,能毫不客氣的拍磚留言,大家互相交流學(xué)習(xí)!
OrderTable.rar
原文地址: cnblogs know
相關(guān)文章
一個(gè)不錯(cuò)的可以檢測(cè)多中瀏覽器的函數(shù)和其它功能
一個(gè)不錯(cuò)的可以檢測(cè)多中瀏覽器的函數(shù)和其它功能...2007-04-04js 點(diǎn)擊a標(biāo)簽 獲取a的自定義屬性方法
下面小編就為大家?guī)?lái)一篇js 點(diǎn)擊a標(biāo)簽 獲取a的自定義屬性方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-11-11React中過(guò)渡動(dòng)畫的編寫方式實(shí)例詳解
在開(kāi)發(fā)中我們想要給一個(gè)組件的顯示和消失添加某種過(guò)渡動(dòng)畫,可以很好的增加用戶體驗(yàn),下面這篇文章主要給大家介紹了關(guān)于React中過(guò)渡動(dòng)畫的編寫方式,需要的朋友可以參考下2022-10-10js 優(yōu)化次數(shù)過(guò)多的循環(huán) 考慮到性能問(wèn)題
IE沒(méi)有我們想象中笨,它知道總的循環(huán)次數(shù)還是一千萬(wàn)次。因此,得把這一百個(gè)十萬(wàn)次循環(huán)分開(kāi)執(zhí)行。雖然Javascript是單線程的,但也可以通過(guò)setTimeout或setInterval模擬多線程。2011-03-03根據(jù)對(duì)象的某一屬性進(jìn)行排序的js代碼(如:name,age)
實(shí)例為按降序排列,若想改為升序只需把比較器中的value2-value1改為value1-value2就可以了2010-08-08詳解JavaScript如何利用異步解密回調(diào)地獄
為了更好地處理這些異步操作,JavaScript?引入了異步編程的概念,這篇文章主要來(lái)和大家詳細(xì)聊聊JavaScript中異步的相關(guān)應(yīng)用,希望對(duì)大家有所幫助2024-02-02