JavaScript表格排序问题:wins列数字19排序位置异常
表格数字列排序异常问题解决
问题现象
对表格的wins列进行排序时,数字19的排序位置异常(本该处于首尾位置,却出现在中间);但1至9的数字排序均正常。
原代码
/** * Sorts a HTML table. * * @param {HTMLTableElement} table The table to sort * @param {number} column The index of the column to sort * @param {boolean} asc Determines if the sorting will be in ascending */ function sortTableByColumn(table, column, asc = true) { const dirModifier = asc ? 1 : -1 const tBody = table.tBodies[0] const rows = Array.from(tBody.querySelectorAll('tr')) // Sort each row const sortedRows = rows.sort((a, b) => { const aColText = a.querySelector(`td:nth-child(${column + 1})`).textContent.trim() const bColText = b.querySelector(`td:nth-child(${column + 1})`).textContent.trim() console.log(aColText) console.log(bColText) return aColText > bColText ? 1 * dirModifier : -1 * dirModifier }) // Remove all existing TRs from the table while (tBody.firstChild) { tBody.removeChild(tBody.firstChild) } // Re-add the newly sorted rows tBody.append(...sortedRows) // Remember how the column is currently sorted table.querySelectorAll('th').forEach(th => th.classList.remove('th-sort-asc', 'th-sort-desc')) table.querySelector(`th:nth-child(${column + 1})`).classList.toggle('th-sort-asc', asc) table.querySelector(`th:nth-child(${column + 1})`).classList.toggle('th-sort-desc', !asc) } export function activeSort() { document.querySelectorAll('.toSort').forEach(headerCell => { headerCell.addEventListener('click', () => { const tableElement = headerCell.parentElement.parentElement.parentElement const headerIndex = Array.prototype.indexOf.call(headerCell.parentElement.children, headerCell) const currentIsAscending = headerCell.classList.contains('th-sort-asc') sortTableByColumn(tableElement, headerIndex, !currentIsAscending) }) }) }
问题原因
代码中直接对单元格的文本内容做字符串比较(aColText > bColText),而字符串是按字典序排序的:比如"19"和"2"比较时,第一个字符"1"的ASCII码小于"2",所以会判定"19" < "2",导致19排在2前面,出现排序异常。
修复方案
将单元格文本转换为数字后再进行比较,修改排序逻辑部分:
const sortedRows = rows.sort((a, b) => { const aColText = a.querySelector(`td:nth-child(${column + 1})`).textContent.trim() const bColText = b.querySelector(`td:nth-child(${column + 1})`).textContent.trim() // 转换为数字进行比较 const aValue = Number(aColText) const bValue = Number(bColText) return (aValue - bValue) * dirModifier })
说明
Number()会把合法的数字字符串转为对应的数值,若列中存在非数字内容,可额外处理NaN的情况- 用
aValue - bValue的结果乘以排序方向系数dirModifier,正数表示a排在b后面,负数则相反,符合数组sort方法的要求。
内容的提问来源于stack exchange,提问作者DaroGawlik
相关产品推荐
相关产品推荐

