我有一个表格,单元格可以放在其中:
这是我正在谈论的一小张桌子:
<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”时,我想按以下方式对表进行排序:
当我再次单击“ Run-4”时,它会执行相反的操作:
我尝试引用几个SO问题,但是在实现它们方面没有成功:
答案 0 :(得分:1)
通常,您会将所有表条目包含在数据结构中,并根据该结构绘制表。对表进行排序会容易得多,因为您只需要对结构进行排序并从中更新表即可。
话虽如此,这是您如何从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() {
...
}
}
在该功能内,您需要做一些事情:
获取当前列的索引,然后遍历该列中的每个单元格。
检查所有单元格是否有红色背景。如果单元格的背景为红色,则将其行克隆到排序的数组中。
检查所有单元格是否为绿色,如果背景为绿色,则将其行克隆到排序后的数组中。
请检查橙色,如果是,请检查yada yada yada。
请检查是否没有背景。在我的代码中,我检查了style参数的缺失,该参数在这种特定情况下适用。但是,如果任何单元格没有背景,但是具有某些内联样式,则它们将不会排序。
用已排序的行替换表的行。
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结构进行排序相比,该解决方案通常更健壮,效率更高,可维护性更好,并且可以将新条目以编程方式添加到表中。