jQuery表格排序时,如何排除首尾<tr>元素?
问题描述
现有表格结构如下:
<table role="presentation" data="regMultipleTable"> <tbody> <tr class="d-none"><td>hide</td><td>hide</td></tr> <tr><td class="d-none">item 1</td><td><font>zebra</font></td></tr> <tr><td class="d-none">item 2</td><td><font>ape</font></td></tr> <tr><td class="d-none">item 3</td><td><font>dog</font></td></tr> <tr class="border-none"><td></td><td><h3>other stuff</h3></td></tr> </tbody> </table>
我需要仅对中间的<tr>元素排序,让首尾的<tr>保持原位,但当前的jQuery逻辑会打乱所有<tr>的顺序。尝试过slice(1, -1)、tr:not(.d-none,.border-none)、tr:not(:first, :last)这些选择器都没解决问题,期望最终效果如下:
<table role="presentation" data="regMultipleTable"> <tbody> <tr class="d-none"><td>hide</td><td>hide</td></tr> <tr><td class="d-none">item 2</td><td><font>ape</font></td></tr> <tr><td class="d-none">item 3</td><td><font>dog</font></td></tr> <tr><td class="d-none">item 1</td><td><font>zebra</font></td></tr> <tr class="border-none"><td></td><td><h3>other stuff</h3></td></tr> </tbody> </table>
当前使用的jQuery代码:
function sortTable(table, order) { var asc = order === 'asc', tbody = table.find('tbody'); /*IN ADDITION TO SLICE() BELOW, I ALSO TRIED: 'tr:not(.d-none,.border-none)' 'tr:not(:first, :last)' */ tbody.find('tr').slice(1, -1).sort(function(a, b) { if (asc) { return window.jQuery('td:eq(1) font', a).text().localeCompare(window.jQuery('td:eq(1) font', b).text()); } else { return window.jQuery('td:eq(1) font', b).text().localeCompare(window.jQuery('td:eq(1) font', a).text()); } }).appendTo(tbody); } sortTable(window.jQuery('table[data="regMultipleTable"]'), 'asc');
解决方案
问题出在appendTo(tbody)这一步:当你把排序后的中间<tr>追加到tbody末尾时,原中间行被移除后,tbody仅剩下首尾两行,追加操作会让排序后的行跑到尾行后面,导致结构错乱。
下面提供两种可行的修改方案:
方案1:重新构建tbody内容
先保存首尾行,清空tbody后按顺序重新添加首尾行和排序后的中间行:
function sortTable(table, order) { var asc = order === 'asc', tbody = table.find('tbody'), // 保存首尾行 firstRow = tbody.find('tr:first'), lastRow = tbody.find('tr:last'), // 获取需要排序的中间行 rowsToSort = tbody.find('tr').slice(1, -1); // 对中间行排序 rowsToSort.sort(function(a, b) { var textA = jQuery('td:eq(1) font', a).text(), textB = jQuery('td:eq(1) font', b).text(); return asc ? textA.localeCompare(textB) : textB.localeCompare(textA); }); // 重新组装tbody内容 tbody.empty() .append(firstRow) .append(rowsToSort) .append(lastRow); } sortTable(jQuery('table[data="regMultipleTable"]'), 'asc');
方案2:插入到尾行之前
无需清空tbody,直接将排序后的中间行插入到尾行的前面:
function sortTable(table, order) { var asc = order === 'asc', tbody = table.find('tbody'), lastRow = tbody.find('tr:last'), rowsToSort = tbody.find('tr').slice(1, -1); // 对中间行排序 rowsToSort.sort(function(a, b) { var textA = jQuery('td:eq(1) font', a).text(), textB = jQuery('td:eq(1) font', b).text(); return asc ? textA.localeCompare(textB) : textB.localeCompare(textA); }); // 将排序后的行插入到尾行之前 rowsToSort.insertBefore(lastRow); } sortTable(jQuery('table[data="regMultipleTable"]'), 'asc');
两种方案都能保证首尾行位置不变,仅对中间行进行排序。
内容的提问来源于stack exchange,提问作者klewis
相关产品推荐
相关产品推荐

