簡體   English   中英

通過單擊表格標題根據單元格背景色對表格進行排序

[英]Sort table based on cell background color by clicking table header

我有一個表格,其中的單元格可以使用:

  1. 無背景色
  2. rgb(255,0,0)
  3. rgb(255,165,0)
  4. rgb(0,128,0)

這是我正在談論的一小張桌子:

 <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css"> <table class="w3-table-all"> <tr><th class="w3-center" style="width: 16.7%;">Name</th><th class="w3-center" style="width: 16.7%;">Run-1</th><th class="w3-center" style="width: 16.7%;">Run-2</th><th class="w3-center" style="width: 16.7%;">Run-3</th><th class="w3-center" style="width: 16.7%;">Run-4</th><th class="w3-center" style="width: 16.7%;">Run-5</th></tr> <tr><th>test1</th><td>9130.47</td><td>392478.721</td><td class="w3-center">-</td><td>44301.148</td><td>44301.148</td></tr> <tr><th>test2</th><td>747505.0087</td><td style="background: rgb(0, 128, 0);">368460.1843</td><td style="background: rgb(0, 128, 0);">64204.7407</td><td style="background: rgb(0, 128, 0);">106400.8238</td><td style="background: rgb(0, 128, 0);">106400.8238</td></tr> <tr><th>test3</th><td>65.01%</td><td style="background: rgb(255, 0, 0);">68.25%</td><td style="background: rgb(255, 0, 0);">69.17%</td><td style="background: rgb(255, 0, 0);">65.07%</td><td style="background: rgb(0, 128, 0);">65.07%</td></tr> <tr><th>test4</th><td>67.53%</td><td>82.72%</td><td>69.67%</td><td>74.29%</td><td>74.29%</td></tr> <tr><th>test5</th><td>-1906.877</td><td style="background: rgb(0, 128, 0);">-103.597</td><td style="background: rgb(0, 128, 0);">-87.119</td><td style="background: rgb(0, 128, 0);">-132.043</td><td style="background: rgb(0, 128, 0);">-132.043</td></tr> <tr><th>test6</th><td>64.86%</td><td style="background: rgb(255, 0, 0);">68.09%</td><td style="background: rgb(255, 0, 0);">72.67%</td><td style="background: rgb(255, 165, 0);">65.56%</td><td style="background: rgb(255, 165, 0);">65.56%</td></tr> </table> 

我想通過單擊任何標題對表進行排序,它將根據該特定列中單元格的顏色對其進行排序。 例如,當您單擊“ Run-4”時,我想按以下方式對表進行排序:

  1. 紅細胞優先
  2. 橙子
  3. 綠色
  4. 沒有顏色

當我再次單擊“ Run-4”時,它會執行相反的操作:

  1. 無色優先
  2. 綠色
  3. 橙子
  4. 紅色

我嘗試引用幾個SO問題,但是在實現它們方面沒有成功:

操作DOM中已經存在的表

通常,您會將所有表條目都放在數據結構中,然后根據該結構繪制表。 對表進行排序會容易得多,因為您只需要對結構進行排序並從中更新表。

話雖如此,這是您如何從DOM中已經存在的表中提取信息並對其進行排序的方法。

首先,您需要獲取相關的行標題單元格,並添加一個click事件監聽器。

var table = document.getElementsByTagName("table")[0],
    rows = table.getElementsByTagName("tr"),
    headers = rows.item(0).getElementsByTagName("th"),
    i, sortOrder = 0;
// start from header 1 not 0 to avoid adding a click
// on the Name header
for ( i=1; i<headers.length; i++ ) {
    headers.item( i ).addEventListener( "click", function() {
        ...
    }
}

在該功能內,您需要做一些事情:

  1. 獲取當前列的索引,然后遍歷該列中的每個單元格。

  2. 遍歷單元格檢查紅色背景。 如果單元格的背景為紅色,則將其行克隆到已排序的數組。

  3. 遍歷所有單元格以檢查綠色,如果背景為綠色,則將其行克隆到排序后的數組中。

  4. 請檢查橙色,如果是,請選擇yada yada yada。

  5. 請檢查是否沒有背景。 在我的代碼中,我檢查了style參數的缺失,該參數在這種特定情況下適用。 但是,如果任何單元格沒有背景,但是具有某些內聯樣式,則它們將不會排序。

  6. 用已排序的行替換表的行。

 window.onload = function() { var table = document.getElementsByTagName("table")[0], rows = table.getElementsByTagName("tr"), headers = rows.item(0).getElementsByTagName("th"), i, sortOrder = 0; // start from header 1 not 0 to avoid adding a click // on the Name header for ( i=1; i<headers.length; i++ ) { headers.item( i ).addEventListener( "click", function() { // Get the index of the header within its row. // This is the same as the column number we'll // be editing var index = Array.prototype.indexOf.call( this.parentNode.children, this ), sortKey = [ "rgb(255,0,0)", "rgb(255,165,0)", "rgb(0,128,0)", "" ], sorted = [], s, j; // initialise static variable for each click function // and increment with each click. If it is even // then sort normally, if odd then reverse the sort if ( !this.sortOrder ) this.sortOrder = 0; if ( this.sortOrder % 2 ) sortKey = sortKey.reverse(); this.sortOrder++; // For each background colour... for ( s = 0; s < sortKey.length; s++ ) { // in each cell in the column... for ( j = 1; j < rows.length; j++ ) { var cell = rows.item(j).children[ index ]; if ( sortKey[s] == "" ) { // If we're on the last sort key.. // and there's no style (so considered // a match) then deep clone into the // sorted array if (cell.outerHTML.indexOf("style") == -1) { sorted.push(rows.item(j).cloneNode(true)); } } else if ( cell.outerHTML.replace(/ /g,'').indexOf(sortKey[s]) != -1) { // If background matches... // clone the node into the sorted array. // Use deep cloning to copy content sorted.push(rows.item(j).cloneNode(true)); } } } for ( j = 1; j < rows.length; j++ ) { rows.item(j).parentNode.replaceChild( sorted[j-1], rows.item(j) ); } }, false ); } } 
 <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css"> <table class="w3-table-all"> <tr><th class="w3-center" style="width: 16.7%;">Name</th><th class="w3-center" style="width: 16.7%;">Run-1</th><th class="w3-center" style="width: 16.7%;">Run-2</th><th class="w3-center" style="width: 16.7%;">Run-3</th><th class="w3-center" style="width: 16.7%;">Run-4</th><th class="w3-center" style="width: 16.7%;">Run-5</th></tr> <tr><th>test1</th><td>9130.47</td><td>392478.721</td><td class="w3-center">-</td><td>44301.148</td><td>44301.148</td></tr> <tr><th>test2</th><td>747505.0087</td><td style="background: rgb(0, 128, 0);">368460.1843</td><td style="background: rgb(0, 128, 0);">64204.7407</td><td style="background: rgb(0, 128, 0);">106400.8238</td><td style="background: rgb(0, 128, 0);">106400.8238</td></tr> <tr><th>test3</th><td>65.01%</td><td style="background: rgb(255, 0, 0);">68.25%</td><td style="background: rgb(255, 0, 0);">69.17%</td><td style="background: rgb(255, 0, 0);">65.07%</td><td style="background: rgb(0, 128, 0);">65.07%</td></tr> <tr><th>test4</th><td>67.53%</td><td>82.72%</td><td>69.67%</td><td>74.29%</td><td>74.29%</td></tr> <tr><th>test5</th><td>-1906.877</td><td style="background: rgb(0, 128, 0);">-103.597</td><td style="background: rgb(0, 128, 0);">-87.119</td><td style="background: rgb(0, 128, 0);">-132.043</td><td style="background: rgb(0, 128, 0);">-132.043</td></tr> <tr><th>test6</th><td>64.86%</td><td style="background: rgb(255, 0, 0);">68.09%</td><td style="background: rgb(255, 0, 0);">72.67%</td><td style="background: rgb(255, 165, 0);">65.56%</td><td style="background: rgb(255, 165, 0);">65.56%</td></tr> </table> 

還實現了反向排序。 變量附加到每個單擊函數,並隨每次單擊遞增。 如果是偶數則搜索將正常執行,如果是奇數,則搜索將反向進行。 單擊多次對不同的列進行排序時,此方法可能導致某些意外行為。

從抽象結構構建表

當前,您的表已經存在於DOM中。 您正在修改其DOM結構以按顏色排序; 也就是說,您想改組已經存在的tr 一種更有效的方法是使表存在於抽象的數據結構中,以便從中提取表。 任何需要進行的排序都將對數據結構進行,而DOM中的表將僅從該結構進行更新。

包含背景顏色和單元格值的數據結構的簡單示例可以用2D數組表示:

[ [ {bg: "", value: "9130.47"},     {bg: "", value: "392478.721"},                {bg: "", value: "-"},                        {bg: "", value: "44301.148"}, ... ],
  [ {bg: "", value: "747505.0087"}, {bg: "rgb(0, 128, 0)", value: "368460.1843"}, {bg: "rgb(0, 128, 0)", value: "64204.7407"}, {bg: "rgb(0, 128, 0)", value: "106400.8238"}, ... ],
  ...
]

那么,填充一個表將是兩個嵌套的for循環的簡單問題,以將單元格添加到它們的適當位置。 您將在單獨的函數中擁有此代碼,以便每當更改數據結構的順序時都可以調用它。

與通過修改當前DOM結構進行排序相比,此解決方案通常更健壯,更高效,具有更好的可維護性,並且可以將新條目以編程方式添加到表中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM