【提出需求】
点击表格头部的时候根据对应列的所有值来进行排序,最终显示排序后的数据行。
【具体效果】
【步骤思路】
点击需要排序列的数据头,获取数据头所在列的索引。通过索引找到每一行所对应列的数据,之后对该列的所有数据进行排序(本实例只进行降序排列),排序结果的每个数据的索引就是该数据所对应行的位置。
【问题解决】
1、如何知道那一列需要排序?
想要知道那些一列的数据需要排序,实现的方法有很多种,但是最重要的一点是必须要知道所点击的头部所在的列数。最简单的方法就是给需要排序的头部添加排序列名,之后判断该点击的头部是否是排序列名(判断的方式也有很多种,本实例使用的是className属性,因为就只有一个类名。还有其他方式getAttribute、match、search、indexOf、lastIndexOf等函数),如果是则执行排序处理代码块,如果不是则不做任何的处理。
if(this.className)
相关知识点:
文章:JavaScript对Html元素的Class操作 - className、classList、Attribute
2、虽然获取了排序列的索引,但是如何获取每一行的所对应列的数据呢?
排序列有一个特征就是相同一列所在行的索引都是相同的,所以获取了排序列的索引之后,只需要获取每一行的节点集合,然后再访问其节点内容的数据列集合,然后再通过索引去访问对应数据列的数据(通过innerText获取数据的文本值,如果数据是数值字符的话,一般会自动转化为数值,不过最好人为转化以下)。
ContTrList[j].getElementsByTagName("td")[this.index].innerText;
相关知识点:
3、虽然获取了每一行的数据,但是如何知道排序后该数据对应的是哪一行数据?
想要解决这个问题也有很多种方式,但是都比较困难,例如可以通过自定义属性,但是这种方式无法解决跨域问题,也可以通过其他数组存储索引等等。本实例使用了二维数组,对每组数组元素的第二个元素赋予该数值对应行的索引值,从而解决无法跨域或者获取麻烦的问题的
for(var j = 0; j < ContTrList.length; j++) {
//该for循环是遍历内容区中的tr标签,并且查找对应的td标签
sortArray[j][0] = ContTrList[j].getElementsByTagName("td")[this.index].innerText;
sortArray[j][1] = j;
}
相关知识点:
注意:排序之前,需要确定行内的数据是数值还是字符串,是升序还是降序等等。通常的方法自然是遍历所有的列数据,看最终返回的结果。本实比较懒,只对第一个进行了判断,在这里安利一波isNaN ()函数。isNaN() 函数用于检查其参数是否是非数字值。如果是非数字值,则返回true,否则返回false。这样我就省去了通过正则表达式去数据是字符还是数值了。
//判断是数值排序还是字符排序
if(!isNaN(sortArray[0][0])){
sortArray.sort(sortNumber);
}else{
sortArray.sort();
}
4、获取了行索引之后,如何更新行数据呢?
索引是无法重复的,所以我们可以通过循环去访问排序后的数值所对应的行索引,这里要注意的是我们获取的只是对应行的节点。所以想要更新数据行也有很多种方法,例如:删除容器内的所有数据行子节点,之后通过遍历一个一个的插入。本实例直接通过拼接数据行的HTML字符串,直接更新父容器的数据行。
//排序完毕之后开始调序
for(var x = 0; x < ContTrList.length; x++) {
newNodeHtml += "<tr>" + ContTrList[sortArray[x][1]].innerHTML + "</tr>";
}
//删除当前内容,插入新的内容
Container.innerHTML = newNodeHtml;
相关知识点:
【最终代码】
//HTML代码
<table border="1" cellpadding="5" style="border-collapse: collapse;text-align: center;">
<tbody>
<tr id="HeadTD">
<td class="sort">姓名</td>
<td class="sort">学号</td>
<td class="sort">语文</td>
<td class="sort">数学</td>
<td class="sort">英语</td>
<td class="sort">总分</td>
<td class="sort">平均分</td>
</tr>
</tbody>
<tbody id="ContTD">
<tr>
<td>张三</td>
<td>220305</td>
<td>11</td>
<td>22</td>
<td>33</td>
<td>22</td>
<td>44</td>
</tr>
<tr>
<td>李四</td>
<td>220302</td>
<td>33</td>
<td>44</td>
<td>66</td>
<td>99</td>
<td>33</td>
</tr>
<tr>
<td>黄五</td>
<td>220307</td>
<td>22</td>
<td>55</td>
<td>22</td>
<td>55</td>
<td>66</td>
</tr>
<tr>
<td>赵六</td>
<td>220303</td>
<td>44</td>
<td>22</td>
<td>33</td>
<td>66</td>
<td>88</td>
</tr>
</tbody>
</table>
//JavaScript代码
window.onload = function() {
var HeadTD = document.getElementById("HeadTD");
var ContTD = document.getElementById("ContTD");
var HeadList = HeadTD.getElementsByTagName("td");
var ContTrList = ContTD.getElementsByTagName("tr");
var sortArray = new Array();
var newNode;
for(var i = 0; i < HeadList.length; i++) {
HeadList[i].index = i;
HeadList[i].onclick = function() {
if(this.className) {
newNode = "";
for(var j = 0; j < ContTrList.length; j++) {
sortArray[j] = new Array();
sortArray[j][0] = ContTrList[j].getElementsByTagName("td")[this.index].innerText;
sortArray[j][1] = j;
}
if(!isNaN(sortArray[0][0])){
sortArray.sort(sortNumber);
}else{
sortArray.sort();
}
for(var x = 0; x < ContTrList.length; x++) {
newNode += "<tr>" + ContTrList[sortArray[x][1]].innerHTML + "</tr>";
}
ContTD.innerHTML = newNode;
}
}
}
}
function sortNumber(b, a) {
if(a > b) {
return 1
} else if(a < b) {
return -1
} else {
return 0
}
}