簡體   English   中英

單擊時的Javascript排序表列

[英]Javascript sort table column on click

我的意圖是在單擊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>

對於描述來說,這看起來也太過分了。 如果您只想對行進行排序,那么該代碼是幾行:

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它的東西,它就會不管它是在第一個地方移動 因此,我們的排序在JS,然后我們運行appendChild在有序,每一行僅僅是從移動“等。無論是”到,該裝置后,我們通過每一行運行“孩子列表的末尾” rows , presto:現在根據需要重新排序所有行。

當然,您仍然需要自己編寫compareValues(a,b) 我不知道你想在那里做什么,因為也許你想要自然文本比較,或者你想要“如果值是數字,則作為數字進行比較,僅當它們不是作為文本進行比較時”等。

但是您應該做的一件事是不要使用 1998 事件處理。 不要使用onclick ,在 JS 端正確執行此操作。 所以在你的 HTML 中:

<tr>
  <th>Nummer</th>
  <th>Land</th>
  <th>Name</th>
</tr>

然后在 JS 方面:

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

(更好的是,使用<th><button>Nummer</button></th>並添加基於th button的事件偵聽th button ,因為它就是這樣。如果您有可以單擊以“做某事”的文本,那是一個按鈕。使用正確的標記,然后只需使用 CSS 設置您想要的樣式,例如無邊框、背景:繼承等)

也許使用不同的方法。 在渲染之前存儲您的數據並對數組進行排序。

 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>

運行您的代碼時,我得到了預期的結果。 我想知道是否僅僅因為您的數據是這樣設置的,結果似乎不正確。

例如,您的數據是:

1   Deutschland Aaron
2   Rumänien    Dan
3   USA Peter

對 Number 進行排序,將有 Deutschland First 和 Aaron,並且 Deutschland 和 Aaron 在其余數據之前按字母順序排在第一位。

因此,其他列正在排序是一種錯覺,而實際上它們實際上只是遵循您的數據結構。

Mike 'Pomax' Kamermans的回答效果很好,除了排序表會將<tr>放在<tbody>標記之外,這是不希望的。 這可以通過更改他的答案來輕松解決:

function sortTable(colnum) {
  let tbody = table.querySelector(`tbody`);
  let rows = Array.from(table.querySelectorAll(`tr`));
  
  // other codes...
  
  rows.forEach(row => tbody.appendChild(row));
  table.appendChild(tbody);
}

然后生成的表應該可以正常工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM