JavaScript表格排序詳解

admin發表於2018-09-19

表格是用來組織資料的,如果數量比較大,並且資料種類眾多的時候,如果能夠按照某種規則進行排序,那麼可能會有利於使用者檢視對比資料,下面就是一段能夠實現此功能的程式碼例項。

程式碼如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!DOCTYPE html> 
<html> 
<head> 
<meta charset=" utf-8"> 
<meta name="author" content="http://www.softwhy.com/" /> 
<title>螞蟻部落</title> 
<style type="text/css"> 
*{ 
  font-family:Arial, Helvetica, sans-serif; 
  font-size:14px; 
  border:none; 
} 
body{ 
  text-align:center; 
} 
table{ 
  margin:100px auto; 
} 
td{ 
  width:100px; 
  height:24px; 
  text-align:center; 
  line-height:24px; 
  border:1px solid silver; 
} 
.red{ 
  color:red; 
} 
.top{
  background:#CCCCCC;
  cursor:pointer;
}
.up{
  background:blue;
}
.down{
  background:green;
}
.hov{
  background:#F0EFE5;
}
</style> 
</head> 
<body> 
<table cellpadding="0" id="table"> 
  <tr class="top"> 
    <td>點選排序</td> 
    <td>點選排序</td> 
    <td>點選排序</td> 
    <td>點選排序</td> 
  </tr> 
  <tr> 
    <td><span id="bfn_la_bac.usa">15.43</span></td> 
    <td class="red">700</td> 
    <td>1.220</td> 
    <td class="red">螞</td> 
  </tr> 
  <tr> 
    <td><span id="bfn_la_c.usa">7.05</span></td> 
    <td class="red">4</td> 
    <td>3,000</td> 
    <td class="red">蟻</td> 
  </tr> 
  <tr> 
    <td><span id="bfn_la_jpm.usa">30.62</span></td> 
    <td class="red">30</td> 
    <td>2,558,800</td> 
    <td class="red">部</td> 
  </tr> 
  <tr> 
    <td><span id="bfn_la_axp.usa">22.30</span></td> 
    <td class="red">5</td> 
    <td>6</td> 
    <td class="red">落</td> 
  </tr> 
  <tr> 
    <td><span id="bfn_la_mrk.usa">26.31</span></td> 
    <td class="red">0.6</td> 
    <td>5</td> 
    <td class="red">奮</td> 
  </tr> 
  <tr> 
    <td><span id="bfn_la_pg.usa">63.16</span></td> 
    <td class="red">7</td> 
    <td>4</td> 
    <td class="red">鬥</td> 
  </tr> 
</table> 
<script type="text/javascript"> 
var tableSort=function(){ 
  this.initialize.apply(this,arguments); 
} 
   
tableSort.prototype={
   
  initialize:function(tableId,clickRow,startRow,endRow,classUp,classDown,selectClass){ 
    this.Table=document.getElementById(tableId); 
    this.rows=this.Table.rows;//所有行 
    this.Tags=this.rows[clickRow-1].cells;//標籤td 
    this.up=classUp; 
    this.down=classDown; 
    this.startRow=startRow; 
    this.selectClass=selectClass; 
    this.endRow=(endRow==999?this.rows.length:endRow); 
    this.T2Arr=this._td2Array();//所有受影響的td的二維陣列 
    this.setShow(); 
  }, 
  //設定標籤切換 
  setShow:function(){ 
    var defaultClass=this.Tags[0].className; 
    for (var Tag, i = 0; Tag = this.Tags[i]; i++) {
      Tag.index = i; 
      addEventListener(Tag ,'click', Bind(Tag,statu)); 
    } 
    var _this =this; 
    var turn = 0; 
 
    function statu(){ 
      for(var i=0;i<_this.Tags.length;i++){ 
        _this.Tags[i].className = defaultClass; 
      } 
      if(turn==0){ 
        addClass(this,_this.down); 
        _this.startArray(0,this.index); 
        turn=1; 
      }
      else{ 
        addClass(this,_this.up) 
        _this.startArray(1,this.index); 
        turn=0; 
      } 
    } 
  }, 
  //設定選中列樣式 
  colClassSet:function(num,cla){ 
    //得到關聯到的td 
    for(var i= (this.startRow-1);i<(this.endRow);i++){ 
      for(var n=0;n<this.rows[i].cells.length;n++){ 
        removeClass(this.rows[i].cells[n],cla); 
      } 
      addClass(this.rows[i].cells[num],cla); 
    } 
  }, 
   
  //開始排序num根據第幾列排序 aord逆序還是順序 
  startArray:function(aord,num){ 
    var afterSort=this.sortMethod(this.T2Arr,aord,num);//排序後的二維陣列傳到排序方法中去 
    this.array2Td(num,afterSort);//輸出 
  }, 
  //將受影響的行和列轉換成二維陣列 
  _td2Array:function(){   
    var arr=[]; 
    for(var i=(this.startRow-1),l=0;i<(this.endRow);i++,l++){ 
      arr[l]=[]; 
      for(var n=0;n<this.rows[i].cells.length;n++){ 
        arr[l].push(this.rows[i].cells[n].innerHTML); 
      } 
   } 
   return arr; 
  }, 
  //根據排序後的二維陣列來輸出相應的行和列的 innerHTML  
  array2Td:function(num,arr){ 
    this.colClassSet(num,this.selectClass);  
    for(var i= (this.startRow-1),l=0;i<(this.endRow);i++,l++){ 
      for(var n=0;n<this.Tags.length;n++){ 
        this.rows[i].cells[n].innerHTML = arr[l][n];  
      } 
    } 
  }, 
   
  //傳進來一個二維陣列,根據二維陣列的子項中的w項排序,再返回排序後的二維陣列 
  sortMethod:function(arr,aord,w){
   
    arr.sort(function(a,b){ 
      x = killHTML(a[w]); 
      y = killHTML(b[w]); 
      x = x.replace(/,/g,''); 
      y = y.replace(/,/g,''); 
      switch (isNaN(x)){ 
        case false: 
          return Number(x) - Number(y); 
          break; 
        case true: 
          return x.localeCompare(y); 
          break; 
      } 
    }); 
    arr = aord==0?arr:arr.reverse(); 
    return arr; 
  } 
} 
/*-----------------------------------*/ 
function addEventListener(o,type,fn){ 
  if(o.attachEvent){o.attachEvent('on'+type,fn)} 
  else if(o.addEventListener){o.addEventListener(type,fn,false)} 
  else{o['on'+type] = fn;} 
} 
   
function hasClass(element, className) {  
  var reg = new RegExp('(\\s|^)'+className+'(\\s|$)');  
  return element.className.match(reg);  
}  
     
function addClass(element, className) {  
  if (!this.hasClass(element, className))  
  {  
   element.className += " "+className;  
  }  
}  
     
function removeClass(element, className) {  
  if (hasClass(element, className)) {  
   var reg = new RegExp('(\\s|^)'+className+'(\\s|$)');  
   element.className = element.className.replace(reg,' ');  
  }  
}  
   
var Bind = function(object, fun) { 
  return function() { 
   return fun.apply(object, arguments); 
  } 
} 
//去掉所有的html標記 
function killHTML(str){ 
  return str.replace(/<[^>]+>/g,""); 
}
var ex1 = new tableSort('table',1,2,999,'up','down','hov'); 
</script> 
</body> 
</html>

以上程式碼實現了我們的要求,下面介紹一下它的實現過程。

一.程式碼註釋:

(1).var tableSort=function(){},建立一個構造方法。

(2).this.initialize.apply(this,arguments),通過apply()方法可以讓initialize()方法能夠接受arguments物件作為引數,arguments物件時實參的封裝。

(3).tableSort.prototype={},重寫建構函式原型物件。

(4).initialize:function(tableId,clickRow,startRow,endRow,classUp,classDown,selectClass){},宣告一個函式,可以用來初始化排序的一些相關內容,比如獲取表格物件,註冊事件處理函式等。tableId是要進行排序的表格的id,clickRow規定點選哪一行進行排序,startRow規定開始排序的行,endRow規定結束排序的行,classUp規定降序的時候標題的樣式,classDown規定升序的時候標題的樣式,selectClass規定當前排序列的背景顏色。

(5).this.Table=document.getElementById(tableId),獲取表格物件。

(6).this.rows=this.Table.rows,獲取表格中所有的行。

(7).this.Tags=this.rows[clickRow-1].cells,獲取標題行所有的單元格。

(8).this.up=classUp,將樣式類名稱賦值給屬性up。

(9).this.down=classDown,將樣式類名稱賦值給屬性down。

(10).this.startRow=startRow,將開始排序的行賦值給屬性startRow。

(11).this.selectClass=selectClass,將樣式類名賦值給屬性selectClass。

(12).this.endRow=(endRow==999?this.rows.length:endRow),如果等999,那麼結束排序的行就是最後一行,否則就是規定的行。

(13).this.T2Arr=this._td2Array(),將所受影響的單元格寫入二維陣列。

(14).this.setShow(),註冊click事件處理函式。

(15).var defaultClass=this.Tags[0].className,獲取第一行第一個單元格的樣式類名稱。

(16).for(var Tag,i=0;Tag=this.Tags;i++){Tag.index = i;addEventListener(Tag ,'click', Bind(Tag,statu));},為標題行每一個單元格註冊click事件處理函式,也就是點選可以進行排序。

(17).var _this =this,將物件的引用賦值給變數_this。

(18).var turn = 0,宣告一個變數作為標記,和設定標題單元格背景色有關。

(19).function statu(){},此函式可以設定標題單元格的背景色交替變化效果。

(20).for(var i=0;i<_this.Tags.length;i++){_this.Tags.className = defaultClass;},將標題所有單元格的背景顏色設定為預設色。

(21).if(turn==0){addClass(this,_this.down);_this.startArray(0,this.index);turn=1;},如果turn等於0,新增當前點選標題的樣式類為_this.down,_this.startArray(0,this.index)進行排序,後面會有介紹,最後將turn的值設定為1。

(22).colClassSet:function(num,cla){},設定當前排序列的樣式,引數num規定當前列的索引,cla規定樣式類名稱。

(23).for(var i= (this.startRow-1);i<(this.endRow);i++){ 

  for(var n=0;n<this.rows.cells.length;n++){ 

    removeClass(this.rows.cells[n],cla); 

  } 

  addClass(this.rows.cells[num],cla); 

}

首先遍歷所有的要排序的單元格,並刪除新增的樣式,然後為當前的排序的列的單元格新增樣式。

(24).startArray:function(aord,num){ 

    var afterSort=this.sortMethod(this.T2Arr,aord,num);

    this.array2Td(num,afterSort);

}, 

此函式用來進行排序,第一個引數規定是哪一列進行排序,第二個引數規定是逆序還是順序排列。var afterSort=this.sortMethod(this.T2Arr,aord,num);將排序後的二維陣列賦值給變數afterSort,this.array2Td(num,afterSort)將排序結果展現出來。

(25). _td2Array:function(){   

    var arr=[]; 

    for(var i=(this.startRow-1),l=0;i<(this.endRow);i++,l++){ 

      arr[l]=[]; 

      for(var n=0;n<this.rows.cells.length;n++){ 

        arr[l].push(this.rows.cells[n].innerHTML); 

      } 

   } 

   return arr; 

}

將可能會進行排序的行和列轉換成一個二維陣列。

(27).array2Td:function(num,arr){ 

    this.colClassSet(num,this.selectClass);  

    for(var i= (this.startRow-1),l=0;i<(this.endRow);i++,l++){ 

      for(var n=0;n<this.Tags.length;n++){ 

        this.rows.cells[n].innerHTML = arr[l][n];  

      } 

    } 

}

將排序後的二維陣列展現出來。

(28).sortMethod:function(arr,aord,w){

  

    arr.sort(function(a,b){ 

      x = killHTML(a[w]); 

      y = killHTML(b[w]); 

      x = x.replace(/,/g,''); 

      y = y.replace(/,/g,''); 

      switch (isNaN(x)){ 

        case false: 

          return Number(x) - Number(y); 

          break; 

        case true: 

          return x.localeCompare(y); 

          break; 

      } 

    }); 

    arr = aord==0?arr:arr.reverse(); 

    return arr; 

  } 

進行排序的函式,第一個引數是要進行排序的陣列物件,第二個是規定逆序還是順序,第三個是要進行排序的列。裡面有兩種排序方式,一種是根據數字大小排序,一種是根據拼音的順序排序。

(29).function addEventListener(o,type,fn){ 

  if(o.attachEvent){o.attachEvent('on'+type,fn)} 

  else if(o.addEventListener){o.addEventListener(type,fn,false)} 

  else{o['on'+type] = fn;} 

註冊事件處理函式,進行了相容性處理。

二.相關閱讀:

(1).push()參閱javascript push()一章節。

(2).cells屬性參閱javascript table cells一章節。

(3).sort()參閱javascript sort()一章節。 

(4).isNaN()參閱JavaScript isNaN()一章節。

(5).Number()參閱javascript Number()一章節。

(6).reverse()參閱js reverse()一章節。

相關文章