【问题标题】:Sorting tables Javascript排序表Javascript
【发布时间】:2019-03-06 19:56:37
【问题描述】:

当用户单击表头时,我正在对表进行排序,并且我正在使用 vanilla Javascript 来执行此操作。我试图通过单击<th> 表头来捕获列号并将其传递给sortTable(n) 函数。另外,我正在尝试在捕获列数据后启动sortTable(n) 函数。我不确定我的错误在哪里?

document.getElementById('myTable2').addEventListener('click', function() {
  myFunction(event)
}, true);

function myFunction() {
  var col = window.event.target.cellIndex;
  var n = col;
  sortTable(n);
  return n;

}

function sortTable(n) {
  var n = myFunction();
  var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
  table = document.getElementById("myTable2");
  switching = true;
  
  dir = "asc";
  while (switching) {
   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.textContenttextContent.toLowerCase() > y.textContent.toLowerCase()) {
          shouldSwitch = true;
          break;
        }
      } else if (dir === "desc") {
        if (x.textContent.toLowerCase() < y.textContent.toLowerCase()) {
          // If so, mark as a switch and break the loop:
          shouldSwitch = true;
          break;
        }
      }
    }
    if (shouldSwitch) {
      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 (switchcount === 0 && dir === "asc") {
        dir = "desc";
        switching = true;
      }
    }
  }
}

【问题讨论】:

    标签: html html-table dom-events columnsorting


    【解决方案1】:

    呸。您将 eventHandler 称为“myFunction()”的方式存在大量编码问题。在变量作用域方面,您还陷入了一些非常危险的习惯。我重写了那些。从好的方面来说,您的应用程序逻辑是合理的。好工作! I wrote a pen that works to show it to you in action if the snippet doesn't。但是,请遵循我关于更改变量名称的建议,尤其是在用于赋值时。

    document.getElementById('myTable2').addEventListener('click', myFunction, true);
    
    function myFunction(event) {
      // window.alert("In myFunction");
      // console.log(event);
      
      var col = event.target.cellIndex;
      //Following line was redundant;
      //var n = col;
      sortTable(col);
      return col;
    
    }
    
    
    //PIECE OF ADVICE: If you renamed the variable "n" to "selectedCol", it would be more readable. Or at least "col"
    function sortTable(n) {
      // WHY are you redeclaring the argument?
      // And why are you assigning myFunction, which called this function, as the object which you are assigning to n?
    //   var n = myFunction();
    
      // OLD VERSION: All declared and set to 0, then later reassigned: Confusing and can get you into problems with variable scope, and unused declarations. 
      // var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
      var switchcount = 0;
      
      var table = document.getElementById("myTable2");
      var switching = true;
      var dir = "asc";
    
      while (switching) {
       switching = false;
       var rows = table.rows;
        var shouldSwitch;
    
        /* Loop through all table rows (except the
        first, which contains table headers): */
        for (var 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: */
          var x = rows[i].getElementsByTagName("TD")[n];
          var 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.textContent.toLowerCase() > y.textContent.toLowerCase()) {
              shouldSwitch = true;
              break;
            }
          } else if (dir === "desc") {
            if (x.textContent.toLowerCase() < y.textContent.toLowerCase()) {
              // If so, mark as a switch and break the loop:
              shouldSwitch = true;
              break;
            }
          }
        }
        if (shouldSwitch) {
          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 (switchcount === 0 && dir === "asc") {
            dir = "desc";
            switching = true;
          }
        }
      }
    }
    table, th, td {
        border: 1px solid black;
        border-collapse: collapse;
    }
    th, td {
        padding: 5px;
    }
    th {
        text-align: left;
    }
    <table id = "myTable2" style="width:100%">
      <tr>
        <th>Firstname</th>
        <th>Lastname</th> 
        <th>Age</th>
      </tr>
      <tr>
        <td>Jill</td>
        <td>Smith</td>
        <td>50</td>
      </tr>
      <tr>
        <td>Eve</td>
        <td>Jackson</td>
        <td>94</td>
      </tr>
      <tr>
        <td>John</td>
        <td>Doe</td>
        <td>80</td>
      </tr>
    </table>

    【讨论】:

    • 感谢您的帮助。我不知道我重新声明了这个论点。有没有办法让标题 作为可点击区域而不是整个列?我假设我需要更改“event.target.cellIndex”
    • 我们很清楚,当你在一个元素上挂起一个 eventListener 时,你有两个选择:你可以在那里定义一个匿名函数,就像你试图做的那样,或者你可以命名它,就像我在解决方案中所做的那样。至于你的第二个问题,我会检查是否event.target.nodeNAME==="TH",如果是真的,只调用sortTable()。编辑:另外,如果你接受了我的回答,你介意点赞吗?
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签