单击Javascript中的标题时,按升序和降序对表进行排序

时间:2019-05-21 04:41:38

标签: javascript sorting

window.addEventListener('DOMContentLoaded', () => {

    let dir = "dsc";

    th = document.getElementsByTagName('th');



    for(let c=0; c < th.length; c++){
      th[c].addEventListener('click',item(c));
    }


    function item(c){
      return function(){
        if (dir == "asc") {
          dir = "dsc";
        }
        else {
          dir = "asc";
        }
        sortTable(c, dir);
      }
    }


  function sortTable(c, sort_dir) {
    let table_rows, switching, i, x, y, shouldSwitch;
    let table = document.getElementsByClassName("results_table");
    switching = true;
    table_rows = table[0].rows;
    while (switching) {
      // Start by saying: no switching is done:
      switching = false;

      for(i=0; i<(table_rows.length-1); i++){

        shouldSwitch = false;

        let present_row = table_rows[i];
        let next_row = table_rows[i+1];
             

        let present_percentage = present_row.cells[1].getElementsByClassName("row_values")[0].cells[1].innerText;
        let next_percentage = next_row.cells[1].getElementsByClassName("row_values")[0].cells[1].innerText;

        let present_percentage_length = present_percentage.length;
        present_percentage = present_percentage.substring(0, present_percentage.length-1);
        let next_percentage_length = next_percentage.length;
        next_percentage = next_percentage.substring(0, next_percentage.length-1);

        if(sort_dir == "asc") {
        if (parseInt(present_percentage, 10) > parseInt(next_percentage, 10)) {
          shouldSwitch = true;
          break;      
        }    
      }

        if(sort_dir == "dsc") {
        if (parseInt(present_percentage, 10) < parseInt(next_percentage, 10)) {
          shouldSwitch = true;
          break;      
        }    
      }

      }

      if (shouldSwitch) {
        table_rows[i].parentNode.insertBefore(table_rows[i + 1], table_rows[i]);
        switching = true;
      }

      
    }
  }
  });
<table class="results_table">
  
    <tr class="record">
      <td>
        <ul>
          <li>email</li>
          <li>address</li>
        </ul>
      </td>
      <td>
        <table class="table_class">
          <tr class="row_header">
            <th>person_status</th>
            <th>Total theory percentage</th>
            <th>Total practicals percentage</th>
          </tr>
          <tr class="row_values">
            <td class="values">
              <td>68%</td>
              <td>88%</td>
            </td>
          </tr>
        </table>
      </td>
    </tr>
    
    <tr class="record">
      <td>
        <ul>
          <li>email</li>
          <li>address</li>
        </ul>
      </td>
      <td>
        <table class="table_class">
          <tr class="row_header">
            <th>person_status</th>
            <th>Total theory percentage</th>
            <th>Total practicals percentage</th>
          </tr>
          <tr class="row_values">
            <td class="values">
              <td>58%</td>
              <td>88%</td>
            </td>
          </tr>
        </table>
      </td>
    </tr>
    <tr class="record">
      <td>
        <ul>
          <li>email</li>
          <li>address</li>
        </ul>
      </td>
      <td>
        <table class="table_class">
          <tr class="row_header">
            <th>person_status</th>
            <th>Total theory percentage</th>
            <th>Total practicals percentage</th>
          </tr>
          <tr class="row_values">
            <td class="values">
              <td>53%</td>
              <td>88%</td>
            </td>
          </tr>
        </table>
      </td>
    </tr>
 </table>

我编写了一个代码,该代码根据单个列中的列值对表行进行排序。现在,代码按升序排序。当表格以升序排列并单击相同的标题时,如何按降序对表格进行排序?这里在主表中有多个表,但是我只是通过获取主表的行进行排序。那是我目前的要求。现在,我可以按升序排序,但无法弄清楚如何在单击标题时添加降序排序。我必须使用香草Javascript来执行此操作。因此,我无法使用jquery或任何其他插件。

编辑:我已经编辑了代码片段。这可以根据问题进行,但是您能告诉我如何以更优雅的JavaScript方式编写代码吗?

1 个答案:

答案 0 :(得分:1)

您在我们的html中有一些错误,我已纠正。之后,可以使用标准的Array.sort()函数来简化JavaScript。您需要通过首先应用element.querySelectorAll()方法将从Array.prototype.slice.call()获得的集合转换为数组。

window.addEventListener('DOMContentLoaded', () => {
    Array.from(document.getElementsByTagName('th'),
               th=>{th.innerHTML='<a href="#" title="click here to sort!" >'+th.innerHTML+'</a>';
                    th.addEventListener('click',sortall)});
})

// access the sortable value in each row of the main table: look for the second row in each 
// sub-table, read the second cell and convert it to a number (by forcing the substraction:"-0")
function getVal(rw){
  return rw.querySelector('table').rows[1].cells[1].textContent.replace('%','')-0;
}

var dir=1;                                            // sort direction (values: 1 or -1)
var table = document.querySelector(".results_table"); // get table element

function sortall()  {
  let rows =  Array.from(table.rows);          // get rows collection as array
  rows.sort((a,b)=>dir*(getVal(a)-getVal(b)))  // sort the rows array
  rows.forEach(r=>table.appendChild(r))        // put rows back into main table
  dir=-dir                                     // toggle sort direction after each call
  return false
}
th a {text-decoration:none}
<table class="results_table">
    <tr class="record">
      <td>
        <ul>
          <li>email</li>
          <li>address</li>
        </ul>
      </td>
      <td>
        <table class="table_class">
          <tr class="row_header">
            <th>person_status</th>
            <th>Total theory percentage</th>
            <th>Total practicals percentage</th>
          </tr>
          <tr class="row_values">
            <td class="values"></td>
            <td>68%</td>
            <td>88%</td>
          </tr>
        </table>
      </td>
    </tr>

    <tr class="record">
      <td>
        <ul>
          <li>email</li>
          <li>address</li>
        </ul>
      </td>
      <td>
        <table class="table_class">
          <tr class="row_header">
            <th>person_status</th>
            <th>Total theory percentage</th>
            <th>Total practicals percentage</th>
          </tr>
          <tr class="row_values">
            <td class="values"></td>
            <td>58%</td>
            <td>88%</td>
          </tr>
        </table>
      </td>
    </tr>

    <tr class="record">
      <td>
        <ul>
          <li>email</li>
          <li>address</li>
        </ul>
      </td>
      <td>
        <table class="table_class">
          <tr class="row_header">
            <th>person_status</th>
            <th>Total theory percentage</th>
            <th>Total practicals percentage</th>
          </tr>
          <tr class="row_values">
            <td class="values"></td>
            <td>13%</td>
            <td>88%</td>
          </tr>
        </table>
      </td>
    </tr>
    <tr class="record">
      <td>
        <ul>
          <li>email</li>
          <li>address</li>
        </ul>
      </td>
      <td>
        <table class="table_class">
          <tr class="row_header">
            <th>person_status</th>
            <th>Total theory percentage</th>
            <th>Total practicals percentage</th>
          </tr>
          <tr class="row_values">
            <td class="values"></td>
            <td>43%</td>
            <td>88%</td>
          </tr>
        </table>
      </td>
    </tr>

</table>