中文漢字排序、
中英文混合排序、
數據大小排序、
文件類型排序(後綴名排序)
日期時間排序、
價格排序、
中文混合數字排序;
使用方法:文檔載入後new tableListSort(arguments,arguments)。
接受兩個參數:第一個參數為必須的,可以是字符串ID,也可以是table對象;第二個可選參數,此參數為一個對象,{data:index,fileType:index,fn:function(){}};對象有三個可選的屬性,第一個和第二個為擴展排序的數據類型,第三個參數為排序後需要執行的函數;如果表格數據中有需要排序的數據大小,如1KB 1MB 1GB 這樣的數據類型的話,可以{data:index};index為表格需排序的某一列的下標值,從0開始計數,如表格的第二列為1KB MB這樣的數據類型,{data:2};對象的第二個屬性{fileType:index},此擴展排序為文件類型,如xml,jpg,exe這樣的後綴名。index同樣為列的下標值。
對象的第三個可選屬性為一個排序後需執行的函數{fn:function(){執行的代碼}}。
HTML代碼中必須的元素為:table元素,table元素的第一行必須使用thead元素包含tr,tr中必須包含可點擊排序的元素th;thead下一個sibling元素必須為tbody,tbody中需包含tr。排序數據使用td包含,table也可以包含caption和tfoot。
4月 11日, 更新:添加了排序後升序降序的標示圖標。
自定義添加class 如果不打算添加 此屬性可以為不設置,鼠標樣式mymickey在腳本裡面加好了不需要CSS添加。
table.Index為上一次被排序過的坐標值;table.Index初始化為null;
fn:fini函數僅為排序過後需要執行的函數,就算沒有它也是可以排序的,這裡傳遞一個排序過後需要執行的函數僅僅是為了添加排序down和up的標示圖標.
以下的源代碼:
復制代碼 代碼如下:
window.onload=function(){
function fini(num){
table.th[num].className=
table.th[num].className=='selectUp'?
'selectDown':'selectUp';//切換標示圖標
each(table.Row,function(o){//highLight高亮當前排序的列
o.cells[num].className='highLight';
if(table.Index!=null&&table.Index!=num){
o.cells[table.Index].className='';
}
});
if(table.Index!=null&&table.Index!=num){//另外的被點擊 原先的被取消表示圖標
table.th[table.Index].className='';
}
}
var table=new tableListSort($('tb'),{data:8,fileType:9,fn:fini})//文檔載入後new傳遞參數
}
復制代碼 代碼如下:
var Class={
create:function(){
return function(){
this.init.apply(this,arguments)
}
}
}
function each(o,fn){
for(var j=0,len=o.length;j<len;j++){
fn(o[j],j)
}
}
Function.prototype.bind=function(){
var method=this;
var args=Array.prototype.slice.call(arguments);
var object=args.shift();
return function(){
return method.apply(object,args.concat(Array.prototype.slice.call(arguments)))
}
}
function $(elem,elem2){
var arr=[];
typeof elem=='string' ?arr.push(document.getElementById(elem)):arr.push(elem);
elem2&&arr.push(arr[0].getElementsByTagName(elem2));
(arr.length>1)&&(typeof elem=='object') &&(arr.shift());
return arr.length!=2?arr[0]:arr[1];
}
var tableListSort=Class.create()
tableListSort.prototype={
init:function(tables,options){
this.table=$(tables);//找到table元素
this.th=$($(this.table,'thead')[0],'th');//找到th元素
this.tbody=$(this.table,'tbody')[0];//找到tbody元素
this.Row=$(this.tbody,'tr'); //找到tr元素
this.rowArr=[];//tr塞入這個數組
this.Index=null;
this.options=options||{};
this.finish=this.options.fn||function(){};
this.dataIndex=Math.abs(this.options.data)||null;//提供比較數據類型的坐標。
this.file=Math.abs(this.options.fileType)||null;//提供需要比較file類型坐標
each(this.Row,function(o){this.rowArr.push(o)}.bind(this));//將tr對象列表載入進數組
for(var i=0;this.th.length>i;i++){
this.th[i].onclick=this.Sort.bind(this,i)//使用bind間接保持一個下標值(變量),傳遞過去
this.th[i].style.cursor='pointer';
}
this.re=/([-]{0,1}[0-9.]{1,})/g;// 替換的正則表達式
this.dataIndex&&subData(this.Row,this.dataIndex,this.Row.length);
},
Sort:function(num){
//var date1=new Date().getTime()//測試用於排序時間 如果想測試排序時間請講注釋去掉
//另外的被點擊 原先的被取消表示圖標
(this.Index!=null&&this.Index!=num)&&this.th[this.Index].setAttribute('sorted','');
this.th[num].getAttribute('sorted')!='ed'?
this.rowArr.sort(this.naturalSort.bind(this,num)):this.rowArr.reverse();
//如果當前對象被點擊過,使用reverse()對應的列直接反序,否則排序,因為使用的是預定義的sort()方法,所以如果要讓執行排序的函數
//知道需要排序的列的下標值的話,bind()傳遞num過去,this來調用;
var frag=document.createDocumentFragment();//創建文檔碎片
each(this.rowArr,function(o){frag.appendChild(o)});//將排序後的數組插入文檔碎片
this.tbody.appendChild(frag);//碎片插入節點
this.th[num].setAttribute('sorted','ed');
//$('spans').innerHTML=(new Date().getTime())-date1;//測試用於排序時間 如果想測試排序時間請講注釋去掉
this.finish(num);//排序後執行的函數
this.Index=num;//被排序過的坐標值
},
naturalSort:function (num,a, b) {
//判斷是否是數據排序 如果是的話 查找屬性
var a=this.dataIndex!=num?a.cells[num].innerHTML:a.cells[num].getAttribute('data'),
b=this.dataIndex!=num?b.cells[num].innerHTML:b.cells[num].getAttribute('data');
//num被bind方法傳遞過來的,找到需排序的單元格裡面的內容
var x = a.toString().toLowerCase() || '', y = b.toString().toLowerCase() || '',
nC = String.fromCharCode(0),
xN = x.replace(this.re, nC + '$1' + nC).split(nC),// 將字符串分裂成數組
yN = y.replace(this.re, nC + '$1' + nC).split(nC),
xD = (new Date(x)).getTime(), yD = (new Date(y)).getTime()
xN = this.file!=num?xN:xN.reverse(),//如果有filetype則反序
yN = this.file!=num?yN:yN.reverse()
if ( xD && yD && xD < yD )
return -1;
else if ( xD && yD && xD > yD )
return 1;
for ( var cLoc=0, numS = Math.max( xN.length, yN.length ); cLoc < numS; cLoc++ )
if ( ( parseFloat( xN[cLoc] ) || xN[cLoc] ) < ( parseFloat( yN[cLoc] ) || yN[cLoc] ) )
//不能轉換為floatNumber直接進行字母比較,如'A'<'B' print//true
return -1;
else if ( ( parseFloat( xN[cLoc] ) || xN[cLoc] ) > ( parseFloat( yN[cLoc] ) || yN[cLoc] ) )
return 1;
return 0;
}
}
function subData(o,i,len){//如果有數據大小排序給td添加一個自定屬性給data//正則也是可以的判斷的//mymickey沒有在這裡寫正則
for(var j=0;len>j;j++){
if(o[j].cells[i].innerHTML.substring(o[j].cells[i].innerHTML.lastIndexOf('KB')).toLowerCase()=='kb'){
o[j].cells[i].setAttribute('data',parseFloat(o[j].cells[i].innerHTML)*1024);
}
if(o[j].cells[i].innerHTML.substring(o[j].cells[i].innerHTML.lastIndexOf('MB')).toLowerCase()=='mb'){
o[j].cells[i].setAttribute('data',parseFloat(o[j].cells[i].innerHTML)*1000000);
}
else if(o[j].cells[i].innerHTML.substring(o[j].cells[i].innerHTML.lastIndexOf('GB')).toLowerCase()=='gb'){
o[j].cells[i].setAttribute('data',parseFloat(o[j].cells[i].innerHTML)*1000000000);
}
}
}
復制代碼 代碼如下:
table#tb {
text-align:center;
border:1px #ccc solid;
border-collapse:collapse;
font-size:12px;
font-family:Arial, Helvetica, sans-serif;
color:#666;
width:900px;
background:url(room-bg.gif) 0 -13px repeat-x ;
}
table#tb td {
border-bottom:#ccc 1px solid;
padding:.3em 0 .3em 0;
}
#tb th {
height:30px;
color:#009;
padding-right:16px;
}
#tb thead tr{
}
#tb td.highLight{color:#000;}
#tb th.selectUp {
background:url(up1.png) no-repeat right center transparent ;
}
#tb th.selectDown {
background:url(down1.png) no-repeat right center transparent ;
}
#tb tfoot{
font-weight:bold;
color:#06F;
background:url(room-bg.gif) 0 -13px repeat-x ;
}
打包下載 http://www.jb51.net/jiaoben/32017.html