[英]Sort table both numerically and alphabetically using Javascript
我有一个表,该表通过单击标题来工作,然后每次单击标题时,该表都会按升序和降序对列进行排序。 它按字母顺序对所有内容进行排序,但我需要它也能够进行数字排序。
在数字超出同一列中的单个数字之前,它似乎一直有效。
这是HTML代码:(忽略NFL内容,仅是测试该表的数据)
<div id="supAll">
<table border="1" class="supTable">
<tr>
<th onclick="sortTable('supTable', 0)">Team</th>
<th onclick="sortTable('supTable', 1)">SB Wins</th>
<th onclick="sortTable('supTable', 2)">SB Losses</th>
<th onclick="sortTable('supTable', 3)">Last Won</th>
</tr>
<tr class="nfc nfcWest">
<td>Arizona Cardinals</td>
<td>0</td>
<td>1</td>
<td>-</td>
</tr>
<tr class="nfc nfcSouth">
<td>Atlanta Falcons</td>
<td>10</td>
<td>2</td>
<td>-</td>
</tr>
<tr class="afc afcNorth">
<td>Baltimore Ravens</td>
<td>2</td>
<td>0</td>
<td>2012</td>
</tr>
<tr class="afc afcEast">
<td>Buffalo Bills</td>
<td>11</td>
<td>4</td>
<td>-</td>
</tr>
<tr class="nfc nfcSouth">
<td>Carolina Panthers</td>
<td>22</td>
<td>2</td>
<td>-</td>
</tr>
<tr class="nfc nfcNorth">
<td>Chicago Bears</td>
<td>1</td>
<td>1</td>
<td>1985</td>
</tr>
<tr class="afc afcNorth">
<td>Cincinnati Bengals</td>
<td>0</td>
<td>2</td>
<td>-</td>
</tr>
<tr class="afc afcNorth">
<td>Cleveland Browns</td>
<td>0</td>
<td>0</td>
<td>-</td>
</tr>
<tr class="nfc nfcEast">
<td>Dallas Cowboys</td>
<td>5</td>
<td>3</td>
<td>1995</td>
</tr>
<tr class="afc afcWest">
<td>Denver Broncos</td>
<td>3</td>
<td>5</td>
<td>2015</td>
</tr>
<tr class="nfc nfcNorth">
<td>Detroit Lions</td>
<td>0</td>
<td>0</td>
<td>-</td>
</tr>
<tr class="nfc nfcNorth">
<td>Green Bay Packers*</td>
<td>4</td>
<td>1</td>
<td>2010</td>
</tr>
<tr class="afc afcSouth">
<td>Houston Texans</td>
<td>0</td>
<td>0</td>
<td>-</td>
</tr>
<tr class="afc afcSouth">
<td>Indianapolis Colts</td>
<td>2</td>
<td>2</td>
<td>2006</td>
</tr>
<tr class="afc afcSouth">
<td>Jacksonville Jaguars</td>
<td>0</td>
<td>0</td>
<td>-</td>
</tr>
<tr class="afc afcWest">
<td>Kansas Chiefs*</td>
<td>1</td>
<td>1</td>
<td>1969</td>
</tr>
<tr class="afc afcWest">
<td>Los Angeles Chargers</td>
<td>0</td>
<td>1</td>
<td>-</td>
</tr>
<tr class="nfc nfcWest">
<td>Los Angeles Rams</td>
<td>1</td>
<td>2</td>
<td>1999</td>
</tr>
<tr class="afc afcEast">
<td>Miami Dolphins</td>
<td>2</td>
<td>3</td>
<td>1973</td>
</tr>
<tr class="nfc nfcNorth">
<td>Minnesota Vikings</td>
<td>0</td>
<td>4</td>
<td>-</td>
</tr>
<tr class="afc afcEast">
<td>New England Patriots</td>
<td>5</td>
<td>4</td>
<td>2016</td>
</tr>
<tr class="nfc nfcSouth">
<td>New Orleans Saints</td>
<td>1</td>
<td>1</td>
<td>2009</td>
</tr>
<tr class="nfc nfcEast">
<td>New York Giants</td>
<td>4</td>
<td>1</td>
<td>2011</td>
</tr>
<tr class="afc afcEast">
<td>New York Jets*</td>
<td>1</td>
<td>0</td>
<td>1968</td>
</tr>
<tr class="afc afcWest">
<td>Oakland Raiders</td>
<td>3</td>
<td>2</td>
<td>1983</td>
</tr>
<tr class="nfc nfcEast">
<td>Philadelphia Eagles</td>
<td>0</td>
<td>2</td>
<td>-</td>
</tr>
<tr class="afc afcNorth">
<td>Pittsburgh Steelers</td>
<td>6</td>
<td>2</td>
<td>2008</td>
</tr>
<tr class="nfc nfcWest">
<td>San Francisco 49ers</td>
<td>5</td>
<td>5</td>
<td>1994</td>
</tr>
<tr class="nfc nfcWest">
<td>Seattle Seahawks</td>
<td>1</td>
<td>2</td>
<td>2013</td>
</tr>
<tr class="nfc nfcSouth">
<td>Tampa Bay Buccaneers</td>
<td>1</td>
<td>0</td>
<td>2002</td>
</tr>
<tr class="afc afcSouth">
<td>Tennessee Titans</td>
<td>0</td>
<td>1</td>
<td>-</td>
</tr>
<tr class="nfc nfcEast">
<td>Washington Redskins</td>
<td>3</td>
<td>2</td>
<td>1991</td>
</tr>
</table>
</div>
</div>
下面是Javascript代码:
function sortTable(tableClass, n) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementsByClassName(tableClass)[0];
switching = true;
dir = "asc";
while (switching) {
switching = false;
rows = table.getElementsByTagName("TR");
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;
}
}
}
}
如果运行代码,您会在中间一栏中看到大小不同的数字,但该数字已不再正确排序。
有什么方法可以使用此代码/功能,以便我的表可以按字母和数字进行排序(当它超过单个数字时)? 如果不能,请帮助我解决此问题。
编辑-这已解决! 如果您同时查看Hendeca和Teldri的以下代码,则将看到已解决的代码。 它们的两个版本都可以工作。
您应该在比较之前将数值解析为整数或浮点型
所以
if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
更改为
if (parseInt(x.innerHTML) > parseInt(y.innerHTML)) {
字符串比较(如果没有数字)
var cmpX=isNaN(parseInt(x.innerHTML))?x.innerHTML.toLowerCase():parseInt(x.innerHTML);
var cmpY=isNaN(parseInt(y.innerHTML))?y.innerHTML.toLowerCase():parseInt(y.innerHTML);
if (parseInt(cmpX) > parseInt(cmpY)) {
将您的功能更改为此:
function sortTable(tableClass, n) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementsByClassName(tableClass)[0];
switching = true;
dir = "asc";
while (switching) {
switching = false;
rows = table.getElementsByTagName("TR");
for (i = 1; i < (rows.length - 1); i++) {
shouldSwitch = false;
x = rows[i].getElementsByTagName("TD")[n];
y = rows[i + 1].getElementsByTagName("TD")[n];
var cmpX=isNaN(parseInt(x.innerHTML))?x.innerHTML.toLowerCase():parseInt(x.innerHTML);
var cmpY=isNaN(parseInt(y.innerHTML))?y.innerHTML.toLowerCase():parseInt(y.innerHTML);
cmpX=(cmpX=='-')?0:cmpX;
cmpY=(cmpY=='-')?0:cmpY;
if (dir == "asc") {
if (cmpX > cmpY) {
shouldSwitch= true;
break;
}
} else if (dir == "desc") {
if (cmpX < cmpY) {
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;
}
}
}
}
如果是数字,则需要将表单元格值转换为数字,如果是名称,则需要将其保留为字符串。 这样做将使两种情况下的比较都可以进行。 这是一些更新的代码:
function sortTable(tableClass, n) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementsByClassName(tableClass)[0];
switching = true;
dir = "asc";
while (switching) {
switching = false;
rows = table.getElementsByTagName("TR");
for (i = 1; i < (rows.length - 1); i++) {
shouldSwitch = false;
x = rows[i].getElementsByTagName("TD")[n];
y = rows[i + 1].getElementsByTagName("TD")[n];
var xContent = (isNaN(x.innerHTML))
? (x.innerHTML.toLowerCase() === '-')
? 0 : x.innerHTML.toLowerCase()
: parseFloat(x.innerHTML);
var yContent = (isNaN(y.innerHTML))
? (y.innerHTML.toLowerCase() === '-')
? 0 : y.innerHTML.toLowerCase()
: parseFloat(y.innerHTML);
if (dir == "asc") {
if (xContent > yContent) {
shouldSwitch= true;
break;
}
} else if (dir == "desc") {
if (xContent < yContent) {
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;
}
}
}
}
通过测试字符串是否为数字,可以确定是否转换该值。 这是相关的更改:
var xContent = (isNaN(x.innerHTML)) ? x.innerHTML.toLowerCase() : parseFloat(x.innerHTML);
var yContent = (isNaN(y.innerHTML)) ? y.innerHTML.toLowerCase() : parseFloat(y.innerHTML);
编辑:添加了一些代码来处理-
字符的情况,并将转换后的数字字符串转换为浮点数,而不是整数来处理十进制数字。 新的检查是:
var xContent = (isNaN(x.innerHTML))
? (x.innerHTML.toLowerCase() === '-')
? 0 : x.innerHTML.toLowerCase()
: parseFloat(x.innerHTML);
var yContent = (isNaN(y.innerHTML))
? (y.innerHTML.toLowerCase() === '-')
? 0 : y.innerHTML.toLowerCase()
: parseFloat(y.innerHTML);
问题实际上是您的数字是字符串。 因此,“ 14”小于“ 4”。 您可以先尝试转换为数字,如果是isNaN,则可以将其作为字符串进行测试,否则可以作为数字进行测试。
_sortTable: function(n, context) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById(context.options.id);
switching = true;
//Set the sorting direction to ascending:
dir = "asc";
/*Make a loop that will continue until
no switching has been done:*/
while (switching) {
//start by saying: no switching is done:
switching = false;
rows = table.getElementsByClassName("row");
/*Loop through all table rows (except the
first, which contains table headers):*/
for (i = 0; i < (rows.length - 1); i++) {
//start by saying there should be no switching:
shouldSwitch = false;
/*Get the two elements you want to compare,
one from current row and one from the next:*/
x = rows[i].getElementsByClassName("cell")[n];
y = rows[i + 1].getElementsByClassName("cell")[n];
/*check if the two rows should switch place,
based on the direction, asc or desc:*/
x = Number(x.innerHTML.toLowerCase()) ? Number(x.innerHTML.toLowerCase()) : x.innerHTML.toLowerCase();
y = Number(y.innerHTML.toLowerCase()) ? Number(y.innerHTML.toLowerCase()) : y.innerHTML.toLowerCase();
if (dir == "asc") {
if (x > y) {
//if so, mark as a switch and break the loop:
shouldSwitch= true;
break;
}
} else if (dir == "desc") {
if (x < y) {
//if so, mark as a switch and break the loop:
shouldSwitch= true;
break;
}
}
}
if (shouldSwitch) {
/*If a switch has been marked, make the switch
and mark that a switch has been done:*/
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
//Each time a switch is done, increase this count by 1:
switchcount ++;
} else {
/*If no switching has been done AND the direction is "asc",
set the direction to "desc" and run the while loop again.*/
if (switchcount == 0 && dir == "asc") {
dir = "desc";
switching = true;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.