很多高手也位jquery寫了專門的排序庫,因?yàn)樽约阂蚕雵L試一下, 當(dāng)然運(yùn)行速度實(shí)在不能接受,但是我會(huì)慢慢的把他改進(jìn)的。
注:這里只是拿出了一部分代碼來,查看演示demo
文檔載入后給'th'添加click事件。
1.
$('th').click(function(){
var date1=(new Date()).getTime()
var dataType=$(this).attr('dataType');
找到點(diǎn)擊對(duì)象的自定義屬性dataType,當(dāng)然這個(gè)不符合W3C的標(biāo)準(zhǔn)是無法通過檢驗(yàn)的,也可以用ID或者class來定義,但是我覺得這樣直觀點(diǎn)在Transitional模式下也可以正常解讀.
2.
var index=$('th').index(this)+1;
找到被點(diǎn)擊對(duì)象在文檔中的位置加上1,加1是為了給所對(duì)應(yīng)的列的td添加樣式才做的。
因?yàn)橛?eq()只能得到td的全文檔位置,而用:nth-child()的話得到的是每個(gè)td在自己的父元素里面的序列位置。
3.
var row=$('tbody tr');
將tbody里所有tr存到變量row.
4.
$.each(row,function(i){ arr[i]=row[i] })
遍歷所有行講它插入arr數(shù)組.
5.if($(this).hasClass('select')){arr.reverse()}
如果這個(gè)'th'被點(diǎn)擊過那么它將會(huì)被添加select樣式,如果是這樣直接將原來的arr數(shù)組反向。
6.
else {
arr.sort(sortStr(index,dataType))
$('.select').removeClass();
$('td:nth-child('+index+')').addClass('select');
$(this).addClass('select')
}
否則,將arr用sort()方法進(jìn)行排序sort()方式可以接受1個(gè)函數(shù),這個(gè)函數(shù)接受2個(gè)參數(shù)作為需要比較的數(shù)據(jù),我在這里定義為
sortStr();
它有兩個(gè)參數(shù):
代碼如下:
function sortStr(index,dataType){
return function(a,b){
var aText=$(a).find('td:nth-child('+index+')').text();
var bText=$(b).find('td:nth-child('+index+')').text();
if(dataType!='roomType'){
aText=Parse(aText,dataType)
bText=Parse(bText,dataType)
return aText>;bText?-1:bText>;aText?1:0;
}
else return aText.localeCompare(bText)
}
}
第一個(gè)是index,它是在click事件中獲得的變量,這個(gè)變量包含了被點(diǎn)擊的那個(gè)'th'的在文檔中的位置是一個(gè)數(shù)字,
jquert的index()方法獲得對(duì)象的位置,這個(gè)位置從0算起,這個(gè)例子中有6個(gè)'th';
第二個(gè)參數(shù)是dataType,他包含每個(gè)'th'的屬性值。
sortStr()里面包含了一個(gè)比較的函數(shù),這個(gè)函數(shù)是匿名函數(shù),它有2個(gè)參數(shù)每個(gè)參數(shù)代表著一個(gè)'tbody tr',(在這里a和b代表需要比較的tr)這兩個(gè)參數(shù)是在包含他的函數(shù)環(huán)境中獲取的,sort()方法里面的參數(shù),在這是一個(gè)函數(shù),這個(gè)函數(shù)都會(huì)獲得數(shù)組對(duì)象的元素,
這個(gè)匿名函數(shù)返回對(duì)操作數(shù)組的引用。
arr里面包含的一個(gè)數(shù)組,每個(gè)數(shù)組的值包含對(duì)tbody里面的tr的引用,排序函數(shù)按照返回的值對(duì)原有數(shù)組里面的元素直接進(jìn)行位置的改變,
var aText=$(a).find('td:nth-child('+index+')').text();
獲取需要比較的行里面其中一個(gè)td里面包含的文本這個(gè)就是需要比較的值,
click事件中得到的index變量成為參數(shù)傳遞到這里就是為了得到th所對(duì)應(yīng)的td的位置;
代碼如下:
if(dataType!='roomType'){
aText=Parse(aText,dataType)
bText=Parse(bText,dataType)
return aText>;bText?-1:bText>;aText?1:0;
}
如果需要排序的類型是不包含了數(shù)字和字母的話,(因?yàn)閾碛衦oomType值的元素所包含了數(shù)字和字母),將獲得的td里面的文本值和dataType傳遞到
Parse()里面進(jìn)行轉(zhuǎn)換,
代碼如下:
function Parse(data,dataType){
switch(dataType){
case 'num':
return parseFloat(data)||0
case 'date':
return Date.parse(data)||0
default :
return splitStr(data)
}
}
如果是數(shù)字類型直接轉(zhuǎn)換為浮點(diǎn)數(shù),
return parseFloat(data)||0
要是出現(xiàn)了布恩那個(gè)轉(zhuǎn)換的對(duì)象字符串那么返回0;因?yàn)檫@個(gè)文檔里面有一個(gè)NaN這個(gè)是無法轉(zhuǎn)換的,所以返回的是0;
如果是日期類型可以用Date.parse直接轉(zhuǎn)換為數(shù)字,這個(gè)轉(zhuǎn)換是從1970年到轉(zhuǎn)換參數(shù)的時(shí)間,
這個(gè)時(shí)間轉(zhuǎn)換我試了試可以精確到秒的,比如說1971/01/2 18:12:20、01/2/1970 18:12:20寫法都可以轉(zhuǎn)換;
之后
return aText>;bText?-1:bText>;aText?1:0;
返回比較值aText比bText大返回一個(gè)小于0的任何數(shù)字都可以,相反返回一個(gè)正數(shù),如果都不是的話返回0;如果不是日期也不是數(shù)字(在這個(gè)文檔中目前只能轉(zhuǎn)換3中數(shù)據(jù):1.日期。2.數(shù)字。3.字符串和數(shù)字一起的),
default :
return splitStr(data)
我把他放到splitStr()里面進(jìn)行轉(zhuǎn)換
splitStr()的內(nèi)容如下:
代碼如下:
function splitStr(data){
var re=/^[\$a-zA-z\u4e00-\u9fa5 ]*(.*?)[a-zA-z\u4e00-\u9fa5 ]*$/
data=data.replace(re,'$1')
return parseFloat(data)
}
正則表達(dá)式:分為三部分 1部分^[a-zA-Z ]*;中間部分(.*?);結(jié)尾部分[a-zA-Z ]*$
可以這樣看/ /是包含塊 ,
第一部分 ^表示目標(biāo)字符串開頭,[]之間表示A-Z無論大小寫都被忽略掉,里面還有個(gè)空格,*表示它左邊[]里面的內(nèi)容可以出現(xiàn)任意次數(shù);
中間部分 ()是個(gè)分組 ,分組內(nèi)容會(huì)被放置到RegExp的第一項(xiàng)中'$1′,'.'匹配所有(除了空格)*?懶惰方式;
最后部分 []之間與后面的*和第一部分是一樣的都是去掉字母,$表示結(jié)尾部分;
\$表示匹配$號(hào)
代碼如下:
function sortStr(index,dataType){
return function(a,b){
var aText=$(a).find('td:nth-child('+index+')').text();
var bText=$(b).find('td:nth-child('+index+')').text();
if(dataType!='roomType'){
aText=Parse(aText,dataType)
bText=Parse(bText,dataType)
return aText>;bText?-1:bText>;aText?1:0;
}
else return aText.localeCompare(bText)
}
}
否則 直接使用localeCompare進(jìn)行比較,這個(gè)是專門對(duì)字符串進(jìn)行比較的方法,如:字符串'a'比字符串'b'排在26的單詞的前面;返回的依然是大于0的數(shù),負(fù)數(shù)和0;
代碼最開頭部分的 new Date和結(jié)束部分的new Date是計(jì)算表格排序時(shí)間的,這個(gè)時(shí)間會(huì)在最中間那個(gè)'th'的'span'標(biāo)記里面顯示出來,這樣是為了測(cè)試整個(gè)表格排序從排序開始到排序結(jié)束所花費(fèi)的時(shí)間。
完整代碼:http://pan.baidu.com/share/link?shareid=197592&uk=85241834