点击时

时间:2019-04-01 19:56:37

标签: javascript html

我的意图是在单击th时以升序对表列(仅单击的列)进行排序。进一步单击时,确切的表列应按降序排列。

到目前为止我得到了什么:
该表正在排序,但是在单击时,所有三列都已排序-我只希望对一列进行排序。

function sortTable(n) {
    var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
    table = document.getElementById("table");
    switching = true;
    dir = "asc";

    while (switching) {
        switching = false;
        rows = table.rows;

        for (i = 1; i < (rows.length - 1); i++) {
            shouldSwitch = false;
            x = rows[i].getElementsByTagName("TD")[n];
            y = rows[i + 1].getElementsByTagName("TD")[n];

            if (dir == "asc") {
                if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
                    shouldSwitch = true;
                    break;
                }
            } else if (dir == "desc") {
                if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
                    shouldSwitch = true;
                    break;
                }
            }
        }
        if (shouldSwitch) {
            rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
            switching = true;
            switchcount ++;
        } else {
            if (switchcount == 0 && dir == "asc") {
                dir = "desc";
                switching = true;
            }
        }
    }
}
<table id="table">
      <tr>
        <th onclick="sortTable(0)">Nummer</th>
        <th onclick="sortTable(1)">Land</th>
        <th onclick="sortTable(2)">Name</th>
      </tr>
      <tr>
        <td>2</td>
        <td>Rumänien</td>
        <td>Dan</td>
      </tr>
      <tr>
        <td>1</td>
        <td>Deutschland</td>
        <td>Aaron</td>
      </tr>
      <tr>
        <td>3</td>
        <td>USA</td>
        <td>Peter</td>
      </tr>
    </table>

3 个答案:

答案 0 :(得分:0)

对于描述来说,这看起来也太过分了。如果您只想对行进行排序,那么该行的代码就是几行:

function compareValues(a, b) {
  // return -1/0/1 based on what you "know" a and b
  // are here. Numbers, text, some custom case-insensitive
  // and natural number ordering, etc. That's up to you.
  // A typical "do whatever JS would do" is:
  return (a<b) ? -1 : (a>b) ? 1 : 0;
}

function sortTable(colnum) {
  // get all the rows in this table:
  let rows = Array.from(table.querySelectorAll(`tr`));

  // but ignore the heading row:
  rows = rows.slice(1);

  // set up the queryselector for getting the indicated
  // column from a row, so we can compare using its value:
  let qs = `td:nth-child(${colnum}`;

  // and then just... sort the rows:
  rows.sort( (r1,r2) => {
    // get each row's relevant column
    let t1 = r1.querySelector(qs);
    let t2 = r2.querySelector(qs);

    // and then effect sorting by comparing their content:
    return compareValues(t1.textContent,t2.textContent);
  });

  // and then the magic part that makes the sorting appear on-page:
  rows.forEach(row => table.appendChild(row));
}

魔术部分之所以起作用,是因为DOM节点只能存在于一个地方,因此,如果将它appendChild appendChild移到某个地方,它就会从最初的位置被移动。这样,我们使用JS进行排序,然后以该排序的顺序运行rows,每一行都简单地从“无论在哪里”移动到“子列表的末尾”,这意味着在我们遍历每个预先存储在compareValues(a,b)中的行中:所有行均未根据需要重新排序。

当然,您仍然需要自己编写onclick。我不知道您要在这里做什么,因为也许您想比较自然的文本,或者也许想要“如果值是数字,则将其作为数字进行比较,仅当它们不作为文本进行比较时”,等等。

但是您应该要做的一件事是不使用1998事件处理。不要使用<tr> <th>Nummer</th> <th>Land</th> <th>Name</th> </tr> ,请在JS端正确执行此操作。因此,在您的HTML中:

table.querySelectorAll(`th`).forEach((th, position) => {
  th.addEventListener(`click`, evt => sortTable(position));
});

然后在JS端:

<th><button>Nummer</button></th>

(而且更好的是,使用th button并基于"([^,]+),([^,]+),([^,]+),'?(.*?)'?$"添加事件侦听器,因为那样就是这样。如果您可以单击文本来“做某事”,那就是一个按钮。使用正确的标记,然后根据需要使用CSS设置样式,例如无边框,背景:继承等)

答案 1 :(得分:0)

也许使用不同的方法。在渲染之前存储数据并对数组进行排序。

let tblData = [{
    number: 2,
    land: 'Rumänien',
    name: 'Dan'
  },
  {
    number: 1,
    land: 'Deutschland',
    name: 'Aaron'
  },
  {
    number: 3,
    land: 'USA',
    name: 'Peter'
  }
];

const getRow = (data) => `<tr><td>${data.number}</td><td>${data.land}</td><td>${data.name}</td></tr>`;

const sortNumber = (a, b) => a.number - b.number;
const sortLand = (a, b) => (a.land === b.land) ? 0 : (a.land > b.land) ? 1 : -1;
const sortName = (a, b) => (a.name === b.name) ? 0 : (a.name > b.name) ? 1 : -1;

function buildTable(data) {
document.querySelector('tbody').innerHTML = data.map(row => getRow(row)).join('');
}

function sortTable(n) {
  let sort = sortNumber;
  switch (n) {
    case 1:
      sort = sortLand;
      break;
    case 2:
      sort = sortName;
  }
  console.log(n);
  buildTable(tblData.sort(sort));
}

buildTable(tblData);
<table id="table">
  <thead>
    <tr>
      <th onclick="sortTable(0)">Nummer</th>
      <th onclick="sortTable(1)">Land</th>
      <th onclick="sortTable(2)">Name</th>
    </tr>
  </thead>
  <tbody>

  </tbody>
</table>

答案 2 :(得分:0)

运行代码时,我得到了期望的结果。我想知道仅仅是因为您的数据是用这种方式设置的,结果似乎还是不正确。

例如,您的数据是:

1   Deutschland Aaron
2   Rumänien    Dan
3   USA Peter

然后对Number进行排序,将Deutschland First和Aaron放在首位,并且在其余数据之前,Deutschland和Aaron都按字母顺序排在第一位。

因此,对其他列进行排序是一种错觉,而实际上它们实际上只是在遵循您的数据结构。