尝试使用w3.js对表格进行排序,但未正确对数字进行排序

时间:2018-11-08 07:05:22

标签: javascript html

我要排序的表如下。

<!DOCTYPE html>
<html>

<title>W3.JS</title>
<meta charset="utf-8">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<script src="https://www.w3schools.com/lib/w3.js"></script>
<body class="w3-container">

<h2>Testing W3.JS with CSS</h2>

<h2>Sort Tables</h2>

<p>Click the table headers to sort the  table accordingly:</p>

<table id="myTable" class="w3-table-all">
  <tr>
    <th onclick="w3.sortHTML('#myTable', '.item', 'td:nth-child(1)')" style="cursor:pointer">Name</th>
    <th onclick="w3.sortHTML('#myTable', '.item', 'td:nth-child(2)')" style="cursor:pointer">Random Number</th>
  </tr>
  <tr class="item">
    <td>Berglunds snabbköp</td>
    <td>6</td>
  </tr>
  <tr class="item">
    <td>North/South</td>
    <td>1</td>
  </tr>
  <tr class="item">
    <td>Alfreds Futterkiste</td>
    <td>2</td>
  </tr>
  <tr class="item">
    <td>Königlich Essen</td>
    <td>5</td>
  </tr>
  <tr class="item">
    <td>Magazzini Alimentari Riuniti</td>
    <td>4</td>
  </tr>
  <tr class="item">
    <td>Paris spécialités</td>
    <td>10</td>
  </tr>
  <tr class="item">
    <td>Island Trading</td>
    <td>6</td>
  </tr>
  <tr class="item">
    <td>Laughing Bacchus Winecellars</td>
    <td>102</td>
  </tr>
</table>

</body>
</html>

似乎可以进行排序的部分代码来自:https://www.w3schools.com/lib/w3.js

w3.sortHTML = function(id, sel, sortvalue) {
  var a, b, i, ii, y, bytt, v1, v2, cc, j;
  a = w3.getElements(id);
  for (i = 0; i < a.length; i++) {
    for (j = 0; j < 2; j++) {
      cc = 0;
      y = 1;
      while (y == 1) {
        y = 0;
        b = a[i].querySelectorAll(sel);
        for (ii = 0; ii < (b.length - 1); ii++) {
          bytt = 0;
          if (sortvalue) {
            v1 = b[ii].querySelector(sortvalue).innerHTML.toLowerCase();
            v2 = b[ii + 1].querySelector(sortvalue).innerHTML.toLowerCase();
          } else {
            v1 = b[ii].innerHTML.toLowerCase();
            v2 = b[ii + 1].innerHTML.toLowerCase();
          }
          if ((j == 0 && (v1 > v2)) || (j == 1 && (v1 < v2))) {
            bytt = 1;
            break;
          }
        }
        if (bytt == 1) {
          b[ii].parentNode.insertBefore(b[ii + 1], b[ii]);
          y = 1;
          cc++;
        }
      }
      if (cc > 0) {break;}
    }
  }
};

如何修改它以便正确地对数字排序?

1 个答案:

答案 0 :(得分:1)

问题在于w3.sortHTML通过(v1 > v2)(v1 < v2)进行排序,其中v1v2分别是文本字符串-当然,这不是考虑数字字符串并按照您期望的方式对它们进行排序。假设您不想胡闹补丁w3.sortHTML,则可以创建自己的功能类似的功能,但是可以使用localeCompare的{​​{1}}选项:

numeric
const myTable = document.querySelector('#myTable');
// select all trs below the header:
const trs = [...myTable.querySelectorAll('tr')].slice(1);

myTable.addEventListener('click', ({ target }) => {
  if (!target.matches('th')) return;
  const thIndex = Array.prototype.indexOf.call(target.parentElement.children, target);
  const getText = tr => tr.children[thIndex].textContent;
  trs.sort((a, b) => getText(a).localeCompare(getText(b), undefined, { numeric: true }));
  trs.forEach(tr => myTable.appendChild(tr));
});

要在单击两次后进行反向排序,请有一个持久对象,该对象可以跟踪按以下顺序排序的最后一个顺序:

<table id="myTable" class="w3-table-all">
  <tr>
    <th style="cursor:pointer">Name</th>
    <th style="cursor:pointer">Random Number</th>
  </tr>
  <tr class="item">
    <td>Berglunds snabbköp</td>
    <td>6</td>
  </tr>
  <tr class="item">
    <td>North/South</td>
    <td>1</td>
  </tr>
  <tr class="item">
    <td>Alfreds Futterkiste</td>
    <td>2</td>
  </tr>
  <tr class="item">
    <td>Königlich Essen</td>
    <td>5</td>
  </tr>
  <tr class="item">
    <td>Magazzini Alimentari Riuniti</td>
    <td>4</td>
  </tr>
  <tr class="item">
    <td>Paris spécialités</td>
    <td>10</td>
  </tr>
  <tr class="item">
    <td>Island Trading</td>
    <td>6</td>
  </tr>
  <tr class="item">
    <td>Laughing Bacchus Winecellars</td>
    <td>102</td>
  </tr>
</table>
const myTable = document.querySelector('#myTable');
// select all trs below the header:
const trs = [...myTable.querySelectorAll('tr')].slice(1);
const sortAscending = {
  0: 1,
  1: 1
};
myTable.addEventListener('click', ({ target }) => {
  if (!target.matches('th')) return;
  const thIndex = Array.prototype.indexOf.call(target.parentElement.children, target);
  const getText = tr => tr.children[thIndex].textContent;
  trs.sort((a, b) => (
    getText(a).localeCompare(getText(b), undefined, { numeric: true })
    * sortAscending[thIndex]
  ));
  trs.forEach(tr => myTable.appendChild(tr));
  sortAscending[thIndex] *= -1;
});