[英]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.