2017-10-17 121 views
1

我有一個表格,它通過點擊一個標題來工作,然後每次單擊標題時按照升序和降序對列進行排序。它按字母順序對所有內容進行排序,但我需要它也能夠按數字排序。使用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,您將看到解決的代碼。他們的兩個版本都有效。

回答

2

你應該分析的數值爲整數或浮點數comparsion之前

所以

if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) { 

變化

if (parseInt(x.innerHTML) > parseInt(y.innerHTML)) { 

串comparsion如果沒有數

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; 
     } 
    } 
} 
} 
+0

嗨,這個偉大的作品整理我的數字列,但它阻止我能夠按字母順序排序我的第一列。現在只有數字可以被排序。 – bevstar7

+0

正如stevelacerda7所解釋的那樣,您可以檢查parseInt是否導致NaN,並在此情況下執行正常的字符串比較。 – teldri

+0

我該怎麼做? – bevstar7

0

問題實際上是你的數字是字符串。所以'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; 
      } 
     } 
    } 
+0

我該怎麼做? – bevstar7

+0

本頁另外兩個答案設法解決了我的問題。感謝您的幫助。 – bevstar7

2

您需要將表格單元格的值轉換爲數字,如果它是一個數字,並把它作爲一個字符串,如果它是一個名字。這樣做會使這兩種情況的比較工作。下面是一些更新的代碼:

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); 
+1

此代碼沒有工作,我認爲是因爲你的改變。我認爲它應該是在上面和外面'if(dir ==「asc」){'如果你在這個頁面上查看其他答案,那麼這個代碼的作用和你的類似。如果您閱讀了我的最新回覆,我有一個新問題......在某些欄目中,我使用' - '作爲空白以表示相當於'N/A',這顯然不是數字。任何包含該符號的列都不能正確分類。有沒有辦法解決?或者一種方法來轉換該符號,使其基本上等於0(不必寫入0)? – bevstar7

+0

@ bevstar7你是對的,它是在錯誤的地方!我還添加了一個測試來處理列中'-'的情況。如果爲了排序目的而遇到'-',則返回'0'。此代碼正在爲我工​​作並處理'-'情況。 – Hendeca

+0

我設法使用其他代碼來解決我的問題(他們也解決了' - '問題),但只是嘗試了你的,它也可行!謝謝您的幫助。 – bevstar7