jQuery sort <table> and <ul>

简介

jQuery实现任意列表或表格实际上非常容易,不需要专门的插件,代码也很短。本站的[文章目录]的排序就是用jQuery实现的。

表格排序

示例代码

$(document).on('click','th',function(){
    var table = $(this).parents('table').eq(0);
    var rows = table.find('tr:gt(0)').toArray().sort(comparer($(this).index()));
    this.asc = !this.asc;
    if (!this.asc){rows = rows.reverse();}
    table.children('tbody').empty().html(rows);
});
function comparer(index) {
    return function(a, b) {
        var valA = getCellValue(a, index), valB = getCellValue(b, index);
        return $.isNumeric(valA) && $.isNumeric(valB) ?
            valA - valB : valA.localeCompare(valB);
    };
}
function getCellValue(row, index){
    return $(row).children('td').eq(index).text();
}

代码分析

概览

一般来说,表格<table>的结构是:

<table>
    <thead>
        <tr>
            <th>head1</th>
            <th>head2</th>
            ...
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>data1</td>
            <td>data2</td>
            ...
        </tr>
        <tr>
            ...
        </tr>
        ...
    </tbody>
</table>

我们希望点击表头就可以对对应的列进行排序,所以通过

$(document).on('click','th',function(){});

监听表头点击

当点击表头时,我们可以通过

var table = $(this).parents('table').eq(0);

获得这个表格的<table>元素

接来下我们希望找到所有列表项,即<tbody>中的所有<tr>

var rows = table.find('tr:gt(0)');

然后就可以对这些<tr>排序了:

var rows = table.find('tr:gt(0)').toArray().sort();

array.sort(compareFunction)是javascript本身支持的方法,我们只需要自定义compareFunction即可实现我们想要的排序。首先我们需要知道对哪一列进行排序,即点击的表头所在的列:

$(this).index()

这样得到列序号后,即可调用compareFunction,如:

var rows = table.find('tr:gt(0)').toArray().sort(comparer($(this).index()));

这样就完成了对所有<tr>的排序。

为了实现可以递增和递减排序,我们可以让每次点击时排序方式都反向,即:

this.asc = !this.asc;
if (!this.asc){rows = rows.reverse();}

最后我们用排序后的<tr>替换原始的<tr>

table.children('tbody').empty().html(rows);

即实现了整个排序过程。

comparer()

array.sort(compareFunction)compareFunction接受两个参数,都是array中的元素,但示例中的comparer()只接受一个元素。实际上comparer()只是将真正用来排序的函数包装了起来,而comparer()的用处就是制定排序的列。

通过

getCellValue(a, index)

可以得到这个<tr>index列的实际值。

为了实现可以对数字和字符串进行排序,我们用

$.isNumeric(valA) && $.isNumeric(valB) ?
    valA - valB : valA.localeCompare(valB);

得到,即如果比较的两个对象都是数值型或可转换为数值型,就以相减的结果作为排序的顺序(javascript中字符串相减会首先将字符串转换为数值型,这样就不用手动转换了);如果有对象不是数值型,则以本地特定的顺序以字符串的形式排序。

getCellValue()

getCellValue()则是需要用户自己定义的,如果你的表格很简单,就可以直接套用示例,但如果你的表格内元素比较复杂,你就需要自己写jQuery选择器,找到你想要用来比较的内容了

示例中

$(row).children('td').eq(index).text();

则是从row这一行,找到第index列的值。

DEMO

jQuery sort table - JSFiddle

列表排序

示例代码

$(document).on('click', 'button', function() {
  var ul = $('#this-ul');
  var rows = ul.children('li').toArray().sort(comparer);
  this.asc = !this.asc;
  if (!this.asc) {
    rows = rows.reverse();
  }
  ul.empty().html(rows);
});

function comparer(a, b) {
  var valA = getCellValue(a),
    valB = getCellValue(b);
  return $.isNumeric(valA) && $.isNumeric(valB) ?
    valA - valB : valA.localeCompare(valB);
}

function getCellValue(row) {
  return $(row).find('.first').text();
}

代码分析

这个和上面的表格排序大同小异,就不再具体解释了。需要注意的地方就是找到<ul>元素,以及自定义的getCellValue()

DEMO

jQuery sort ul - JSFiddle

参考