Javascript 使用可展开部分对表数据进行排序

Javascript 使用可展开部分对表数据进行排序,javascript,jquery,html,Javascript,Jquery,Html,现在我有这个: <style> table { border-spacing: 0; width: 100%; border: 1px solid #ddd; } th, td { text-align: left; padding: 16px; } tr:nth-child(even) { background-color: #f2f2f2 } </style> <

现在我有这个:

<style>
  table {
      border-spacing: 0;
      width: 100%;
      border: 1px solid #ddd;
  }

  th, td {
      text-align: left;
      padding: 16px;
  }

  tr:nth-child(even) {
      background-color: #f2f2f2
  }
</style>
<table id="schInfoTable">
  <thead>
    <th onclick="sortTable(0)">Date</th>
    <th>Amount</th>
    <th>Count</th>
  </thead>
  <tbody>
    <tr>
      <td><a onclick="openView('2018-11-14')">2018-11-14</a></td>
      <td>$23,000.00</td>
      <td>12</td>
    </tr>
    <tr style="display:none; background-color: #cbe7cb;" class="2018-11-14">
      <td>Mandy</td>
      <td>Designer</td>
      <td>View</td>
    </tr>
    <tr style="display:none; background-color: #cbe7cb;" class="2018-11-14">
      <td>Robert</td>
      <td>Cook</td>
      <td>View</td>
    </tr>
    <tr>
      <td><a onclick="openView('2018-11-13')">2018-11-13</a></td>
      <td>$13,000.00</td>
      <td>8</td>
    </tr>
    <tr style="display:none; background-color: #cbe7cb;" class="2018-11-13 branches">
      <td>James</td>
      <td>Driver</td>
      <td>View</td>
    </tr>
  </tbody>
</table>
<script>

  function openView(showID){
        $("."+showID).toggle();
    }

  function sortTable(n) {

      var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
      table = document.getElementById("schInfoTable");
      switching = true;
      //Set the sorting direction to ascending:
      dir = "asc"; 
      /*Make a loop that will continue until
      no switching has been done:*/
      while (switching) {
        //start by saying: no switching is done:
        switching = false;
        rows = table.rows;
        /*Loop through all table rows (except the
        first, which contains table headers):*/
        for (i = 1; i < (rows.length - 1); i++) {
          //start by saying there should be no switching:
          shouldSwitch = false;
          /*Get the two elements you want to compare,
          one from current row and one from the next:*/
          x = rows[i].getElementsByTagName("TD")[n];
          y = rows[i + 1].getElementsByTagName("TD")[n];
          /*check if the two rows should switch place,
          based on the direction, asc or desc:*/
          if (dir == "asc") {
            if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
              //if so, mark as a switch and break the loop:
              shouldSwitch= true;
              break;
            }
          } else if (dir == "desc") {
            if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
              //if so, mark as a switch and break the loop:
              shouldSwitch = true;
              break;
            }
          }
        }
        if (shouldSwitch) {
          /*If a switch has been marked, make the switch
          and mark that a switch has been done:*/
          rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
          switching = true;
          //Each time a switch is done, increase this count by 1:
          switchcount ++;      
        } else {
          /*If no switching has been done AND the direction is "asc",
          set the direction to "desc" and run the while loop again.*/
          if (switchcount == 0 && dir == "asc") {
            dir = "desc";
            switching = true;
          }
        }
      }
    }
</script>

桌子{
边界间距:0;
宽度:100%;
边框:1px实心#ddd;
}
th,td{
文本对齐:左对齐;
填充:16px;
}
tr:n个孩子(偶数){
背景色:#F2F2
}
日期
数量
计数

单击日期时,它将展开并显示附加表行及其数据:

但当您在order sort by Date(按日期排序)中单击日期标题时,一切都会出错:

正如您所看到的,绿色高亮显示的表格数据一起放在底部,但它们应该是这样的:

我如何做到这一点

更新:多亏了David784的代码,我才能够得到想要的结果,虽然我做了一些小动作,但都归功于David。以下是我现在拥有的:

function openView(showID) {
  $("." + showID).toggle();
}

function sortTable(n) {

  var table, rows, i, x, y = 0;
  var compare1, compare2;
  table = document.getElementById("schInfoTable");
  switching = true;

  rows = table.querySelectorAll('tr.sort');

  var sortArr = [];
  for (i = 0; i < rows.length; i++) {
    x = rows[i];
    if (i + 1 in rows) y = rows[i + 1].previousElementSibling;
    else y = x.parentElement.lastChild;
    var obj = {
      sort: x.getElementsByTagName("TD")[n].textContent.toLowerCase(),
      range: document.createRange()
    };
    obj.range.setStartBefore(x);
    obj.range.setEndAfter(y);
    sortArr.push(obj);
  }
  function fnSortArrAsc(a, b) {
    if (a.sort > b.sort) return 1;
    else if (a.sort < b.sort) return -1;
    else return 0;
  }
  function fnSortArrDesc(a, b) {
    if (a.sort < b.sort) return 1;
    else if (a.sort > b.sort) return -1;
    else return 0;
  }

  compare1 = rows[0].getElementsByTagName("TD")[0].textContent.toLowerCase();
  compare2 = rows[rows.length-1].getElementsByTagName("TD")[0].textContent.toLowerCase();
  if(compare1 < compare2){
    sortArr = sortArr.sort(fnSortArrDesc);
  }else{
    sortArr = sortArr.sort(fnSortArrAsc);
  }

  frag = document.createDocumentFragment();
  for (i = 0; i < sortArr.length; i++) {
    x = sortArr[i];
    frag.appendChild(x.range.extractContents());
  }
  table.appendChild(frag);
}
函数openView(showID){
$(“+showID).toggle();
}
函数可排序(n){
变量表,行,i,x,y=0;
var compare1,compare2;
table=document.getElementById(“schinfo表”);
切换=真;
行=table.querySelectorAll('tr.sort');
var-sortArr=[];
对于(i=0;ib.sort)返回1;
否则如果(a.sortb.sort)返回-1;
否则返回0;
}
compare1=行[0]。getElementsByTagName(“TD”)[0]。textContent.toLowerCase();
compare2=行[rows.length-1]。getElementsByTagName(“TD”)[0]。textContent.toLowerCase();
if(compare1

完整的工作代码如下:

假设您希望保持表结构几乎相同,那么这将是完成您尝试执行的操作的一种方法

javascript的简要描述:

假设:
  • 在每个“顶级”TR上添加类。这些是被排序的行
  • 假设任何非顶级TR是其上方顶级TR的一个子行,并将随该行一起移动
方法论
  • querySelectorAll
    中,使用添加到顶级TRs的新类来获取要排序的所有内容的列表
  • 循环:创建对象数组,包括
    • 排序值(正确TD的小写字符串内容)
    • 行及其下所有子行的DOM范围
  • 然后使用内置javascript
    Array.sort
    和简单的自定义排序功能
  • 循环:按顺序将所有范围内容提取到documentFragment中
  • 将documentFragment追加回表
我使用documentFragment的原因是,与将每个范围一次一个地直接添加回表元素相比,它节省了DOM回流和渲染的时间(如上所述)

注意:如果您有一个表尾,您可能希望使用
tbody
元素,而不是直接处理表

函数openView(showID){
$(“+showID).toggle();
}
函数可排序(n){
变量表,行,切换,i,x,y,shouldSwitch,dir,switchcount=0;
table=document.getElementById(“schinfo表”);
切换=真;
//设置排序方向
dir=1;
var-thEl=table.querySelectorAll('th')[n];
if(thEl.classList.contains('asc'))dir=-1;
toggle('asc');
行=table.querySelectorAll('tr.sort');
var-sortArr=[];
对于(i=0;ib.sort)返回1*dir;
否则如果(a.sort
表格{
边界间距:0;
宽度:100%;
边框:1px实心#ddd;
}
th,
运输署{
文本对齐:左对齐;
填充:16px;
}
tr:n个孩子(偶数){
背景色:#F2F2
}

日期
数量
计数
2018-11-14
$23,000.00
12
曼迪
设计师
看法
罗伯特
烹调
看法
2018-11-13
$13,000.00
8.
詹姆斯
司机
看法

我对你的问题非常感兴趣,我把我的想法编入了程序。 我希望这篇文章能对你有所帮助

让testData=[{
日期:“2018-11-14”,
金额:23000,
计数:12,
人民:[{
姓名:“曼迪”,
名称:“设计师”,
详情:“查看”,
},
{
姓名:“