创建一个通用的 sortableTable 对象,用于在每次单击列时仅使用 JavaScript 按字母顺序对 table 元素进行排序

Create a generic sortableTable object to be used to alphabetically sort a table elements each time a column is clicked using only JavaScript

我正在开发不使用 jQuery 而只使用 JavaScript 的项目,我们需要按字母顺序升序排序 table 值(没有任何外部库) .

objective是每点击一列(个元素)就对行元素进行排序。

例子

如果我有这个table

当我点击 "Names" 时,table 应该像这样刷新:

当我点击 "Tel" 时,table 应该像这样刷新:

我在这里分享我自己的解决方案。如果您有任何意见或建议,请分享。

我正在通过添加逆序功能来更新我的解决方案:

  • 例如,当您第一次单击 姓名 时,table 将刷新为 姓名的升序
  • 当您第二次单击 姓名 时,table 将刷新为 降序 的姓名。
  • 当您第 3 次单击 姓名 时,table 将刷新为 姓名的升序
  • 等...

var sortableTable = {
 /**
 * The table to sort
 */
 table: null,
 getTable: function(){
  return this.table;
 },
 setTable: function(table){
  this.table = table;
 },
 /**
 * The column used for sorting
 */ 
 element: null,
 getElement: function(){
  return this.element;
 },
 setElement: function(element){
  this.element = element;
 },
    /**
    * When ooderDirection is 1 => Ascending order 
    * When ooderDirection is -1 => Descending order 
    */
 orderDirection: 1,
 getOrderDirection: function(){
  return this.orderDirection;
 },
 setOrderDirection: function(orderDirection){
  this.orderDirection = orderDirection;
 },
 /**
 * Get table rows elements
 */  
 getRows: function(){
  var rows = [];
  if(null !== this.getTable()){
   var allRows = this.getTable().rows;
   /*
    When I returned allRows directly, 
    in the sort function when I do: rows.sort();
    it display an error: Uncaught TypeError: rows.sort is not a function
    So I'm converting this object to an array
   */
   var arrayRows = [];
   //allRows contains all rows with <th> elements, 
   //so I'm removing th elements (index 0)
   for(let i=1 ; i<allRows.length ; i++){
    arrayRows.push(allRows[i]);
   }
   return (arrayRows);
  }
  return null;
 },
 /**
 * Display rows using the sort result
 */  
 refresh: function(rows){
  for(let i=0 ; i<rows.length ; i++){
   this.getTable().appendChild(rows[i]);
  }
 },
 /**
 * Sort alphabetically (ASC)
 */  
 sort: function(indexOfClickedTh){
  var rows = this.getRows();
        var that = this;
  rows.sort(function(item1, item2){
   var contentItem1 = item1.getElementsByTagName('td')[indexOfClickedTh].innerText;
   var contentItem2 = item2.getElementsByTagName('td')[indexOfClickedTh].innerText;
   let resultCompare = contentItem1.localeCompare(contentItem2);
            resultCompare = resultCompare * that.getOrderDirection();
   //console.info('comparing(' + contentItem1 + ', ' + contentItem2 + ')=' + resultCompare); 
   return resultCompare;
  });
  this.refresh(rows);
 }
}


//The first click will generate an ascending sort
var initialOderDirection = -1;

var myTableToSort = document.getElementById('users');
sortableTable.setTable(myTableToSort);
sortableTable.setOrderDirection(initialOderDirection);
var ListOfTh = document.getElementById('users').getElementsByTagName('th');
for(var i=0 ; i<ListOfTh.length ; i++){
 var oneTh = ListOfTh[i];
 oneTh.addEventListener("click", function(){
        //console.info("------> New sort based on '" + this.innerText + "' <------");
      
        // Set the current clicked <th> element
  sortableTable.setElement(this);
      
        //Inverse the order
        sortableTable.setOrderDirection( sortableTable.getOrderDirection() * -1 );
        
        //Do the sort and refresh table result
  sortableTable.sort(this.cellIndex); 
 });
};
table{
    font-size: 16px;
    border-collapse: collapse;
    border-spacing: 0;
    width: 100%;
}
table th{
    padding-top: 11px;
    padding-bottom: 11px;
    background-color: #6295a5;
    color: white;
}
table td{
    border: 1px solid #ddd;
    text-align: left;
    padding: 8px;
}
table tr:nth-child(even) {
    background-color: #f2f2f2;
}
table th{
 cursor: pointer;
}
table th:hover{
 color: #dea82e;
 background-color: #37545d;
}
<table id="users">
 <thead>
  <tr>
   <th>Names</th>
   <th>Functions</th>
   <th>Emails</th>
   <th>Tel</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>xMxxx</td>
   <td>Physicists</td>
   <td>xmxxx@domain.com</td>
   <td>00 55 99 99 99</td>
  </tr>
  <tr>
   <td>xJxxx</td>
   <td>Air Traffic Controllers</td>
   <td>xjxxx@domain.com</td>
   <td>00 22 99 99 99</td>
  </tr>
  <tr>
   <td>xExxx</td>
   <td>Engineer</td>
   <td>xexxx@domain.com</td>
   <td>00 33 99 99 99</td>
  </tr>
  <tr>
   <td>xAxxx</td>
   <td>Mechanical engineer</td>
   <td>xaxxx@domain.com</td>
   <td>00 11 99 99 99</td>
  </tr>
  <tr>
   <td>xZxxx</td>
   <td>Doctor</td>
   <td>xzxxx@domain.com</td>
   <td>00 44 99 99 99</td>
  </tr>
  <tr>
   <td>xPxxx</td>
   <td>Professor</td>
   <td>xpxxx@domain.com</td>
   <td>00 66 99 99 99</td>
  </tr>
 </tbody>
</table>