3User.com 三人行社区3User.com 三人行社区
3user特别推荐:

绑定MSN/QQ/GTalk

获取网站更新(帮助)

JS版本表格排序 [ Table Sort ]

发新帖
«» 4 

JS版本表格排序 [ Table Sort ]

zhaozy

于 08-02-28 12:28 通过网页 帖子号: 14194

JS版本表格排序 [ Table Sort ]

关键字: Array对象, sort(), DOM

JavaScript中的Array对象

Array用于在单独变量名中存放一系列的值.

对Array对象常用的方法 [ 行为 ] 有: concat(), join(), pop(), push(), reverse(), shift(), slice(), sort(), splice(), toString()等.

在这个话题中会选用Array.sort()这个方法作为主要原理, 辅以reverse()进行倒序控制.

数字排序

sort()方法默认是按照数组单元的ASCII字符码进行排列, 也就是说不适合我们一般意义上的数字排序.

var arr = [1,15,35,10,5];
arr.sort();
alert(arr.toString());

 输出的会是: 1, 10, 15, 35, 5, 这时,就要用到sort()方法中可以接受的一个参数 - 比较函数.

这个比较函数返回3种状态: 进行比较的值之间是大于, 小于还是等于.

这个函数可能会是这样:

function comparison(value1, value2){
    if(value1 < value2){
        return -1;
    }else if(value1 > value2){
        return 1;
    }else{
        return 0;
    }
}

 调用的时候使用:

arr.sort(comparison);

更进一步, 我们对传入的两个参数进行控制, 把传入的参数转换成数字:

function comparison(value1, value2){
    var iNum1 = parseInt(value1);
    var iNum2 = parseInt(value2);
    if(iNum1 < iNum2){
        return -1;
    }else if(iNum1 > iNum2){
        return 1;
    }else{
        return 0;
    }
}

字符排序

那么更简单的, 调用String对象中的LocaleCompare()方法即可完成对字符和数字的比较.

reverse()方法

简单地说, 就是将数组中元素的顺序倒转.

step - 1 入门: 单列表格的排序

表格结构:

<table cellspacing="0" id="needSort">
    <caption>User End Design</caption>
    <thead>
        <tr>
            <th scope="col">Type</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Graphic Design</td>
        </tr>
        <tr>
            <td>(X)HTML</td>
        </tr>
        <tr>
            <td>CSS</td>
        </tr>
        <tr>
            <td>JavaScript</td>
        </tr>
    </tbody>
</table>

 示意代码如上, 注意要将表头行和数据行分离, 使用表格的 tBodies 元素组获取表格中tbody元素及它所有的子元素.

比较函数:

function comparison(tr1, tr2){
    var value1= tr1.cells[0].firstChild.nodeValue;
    var value2= tr2.cells[0].firstChild.nodeValue;
    return value1.localeCompare(value2);
}

 这个函数是根据每行第一个单元格的值进行排序

排序函数:

Step 1:

function tableSort(id){
    var _table = document.getElementById(id);
    var _tbody = _table.tBodies[0];
    var _dataGrids = _tbody.rows;
}

 这里对需要进行处理的数据所在的容器做了定位,rows是DOM集合, 并不是像它表现出来的数组形式. 所以它没有sort()方法.我们要做的是要自己构建一个代表rows的数组.

step 2:

function tableSort(id){
    var _table = document.getElementById(id);
    var _tbody = _table.tBodies[0];
    var _dataGrids = _tbody.rows;
    var _trow = new Array();

    for(var i=0; i<_dataGrids.length; i++){
        _trow.push(_dataGrids[i]);
    }

    _trow.sort(comparison);
}

这里把所有的tr对象都存入_trow数组中,然后对_trow数组应用sort()方法. 在数组中, 元素已经排列好了, 剩下的事情就是处理页面显示了.

我们可以直接用 _tbody.appendChild 来循环修改表格, 也可以通过创建文档片段来一次性修改.

function tableSort(id){
    var _table = document.getElementById(id);
    var _tbody = _table.tBodies[0];
    var _dataGrids = _tbody.rows;
    var _trow = new Array();

    for(var i=0; i<_dataGrids.length; i++){
        _trow.push(_dataGrids[i]);
    }

    _trow.sort(comparison);

    //var _fragment = document.createDocumentFragment();
    for(var i=0;i<_trow.length;i++){
        //_fragment.appendChild(_trow[i]);
        _tbody.appendChild(_trow[i]);
    }
   //_tbody.appendChild(_fragment);
}

蓝色部分代码是循环修改, 红色部分代码是创建文档片段一次性创建.

剩下来的事情就是绑定用户行为了,

<table cellspacing="0" id="needSort" border="1">
    <caption>User End Design</caption>
    <thead>
        <tr>
            <th scope="col" onclick="tableSort('needSort')">Type</th>
        </tr>
    </thead>
......

这里有悖于无侵入编程的原则, 唔, 不爽, 先留着慢慢改. 在可以通过定义CSS来给thead / tr / th 添加鼠标样式: cursor:pointer .

楼主

mscript script editor + instant source + ie dev toolbar + httpwatch PK Firebug

zhaozy

08-02-28 15:56 通过网页

回复:JS版本表格排序 [ Table Sort ]

单列表格的例子完毕, 很简单不是吗? 但是在实际应用中, 很少会遇到单列表格吧... 那我们也要进一步了.

多列表格排序


<table cellspacing="0" id="needSort" class="needSort">
    <caption>User End Design</caption>
    <thead>
        <tr>
            <th scope="col">Type</th>
            <th scope="col">Editor</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Graphic Design</td>
            <td>Photoshop</td>
        </tr>
        <tr>
            <td>(X)HTML</td>
            <td>DreamWeaver</td>
        </tr>
        <tr>
            <td>CSS</td>
            <td>StyleTop</td>
        </tr>
        <tr>
            <td>JavaScript</td>
            <td>EditPlus</td>
        </tr>
    </tbody>
</table>

 之前的比较函数限制较多, 现在通过传递参数的方法打开限制.

function generateCompare(ind){
    return function comparison(tr1, tr2){
        var value1= tr1.cells[ind].firstChild.nodeValue;
        var value2= tr2.cells[ind].firstChild.nodeValue;
        return value1.localeCompare(value2);
    }
}

这样就能对任意列的数据进行比较了. 只需要一个表列的索引即可.

恩,构建一个无侵入的脚本吧.

var _table = document.getElementsByTagName("table");
for(var i=0;i<_table.length;i++){
    if(_table[i].className){
        if(_table[i].className=="needSort"){
            var _thead = _table[i].getElementsByTagName("thead")[0];
            var _tr = _thead.rows[0];
            var _th = _tr.cells;
            for(var j=0;j<_th.length;j++){
                _th[j].onclick = tableSort;
            }
        }
    }
}

所有定义了 class="needSort" 的table都可以调用这段代码了.

我们再来看tableSort 这个函数:

function tableSort(ev){
    var ev = ev || window.event;
    var _target = ev.target || ev.srcElement;
    var _parent = _target.parentNode;
    var _children = new Array();
    var _tableCur = _parent.parentNode.parentNode;
    var _tbody = _tableCur.tBodies[0];
    var _cellGrids;
    for(var i=0;i<_parent.childNodes.length;i++){
         if(_parent.childNodes[i].nodeType=="1"){
             _children.push(_parent.childNodes[i]);
         }
    }

    for(var i=0;i<_children.length;i++){
        if(_target==_children[i]){
            _cellGrids = getColumnArray(i,_tableCur);
            var _fragment = document.createDocumentFragment();
            for(var j=0;j<_cellGrids.length;j++){
                _fragment.appendChild(_cellGrids[j])
            }
            _tbody.appendChild(_fragment)
        }else{
            continue;
        }
    }
}

标识出2块代码段, 这两块代码段都是为兼容IE和Firefox准备的, Firefox中没有window.event事件, IE中没有把硬回车算成一个节点. Firefox和IE的兼容问题...有空再整理. 这里就先带过了.

其中我把组成列数组的部分单独提出来作为一个函数, 只是为了看上去清楚一点...

function getColumnArray(ind,tab){
    var _tbody = tab.tBodies[0];
    var dataGrids = _tbody.rows;
    var _trow = new Array();
    for(var i=0; i<dataGrids.length; i++){
        _trow.push(dataGrids[i]);
    }
    _trow.sort(generateCompare(ind));
    return _trow;
}

 这样一个多列表格的排序也完成了. 唔, 离我们的目标更近了一步.

1楼

mscript script editor + instant source + ie dev toolbar + httpwatch PK Firebug

zhaozy

08-02-28 16:45 通过网页

回复:JS版本表格排序 [ Table Sort ]

倒序排列

这部分就非常简单了, 只要用到Array对象的reverse()方法就基本搞定了.

修改过的函数有2个:

function getColumnArray(ind,tab,obj){
    var _tbody = tab.tBodies[0];
    var dataGrids = _tbody.rows;
    var _trow = new Array();
    for(var i=0; i<dataGrids.length; i++){
        _trow.push(dataGrids[i]);
    }
    if(obj.sortType && obj.sortType=="asc"){
        _trow.reverse();
    }else{
        _trow.sort(generateCompare(ind))
    }
    return _trow;
}

function tableSort(ev){
    var ev = ev || window.event;
    var _target = ev.target || ev.srcElement;
    var _parent = _target.parentNode;
    var _children = new Array();
    var _tableCur = _parent.parentNode.parentNode;
    var _tbody = _tableCur.tBodies[0];
    var _cellGrids;
    for(var i=0;i<_parent.childNodes.length;i++){
        if(_parent.childNodes[i].nodeType=="1"){
            _children.push(_parent.childNodes[i]);
        }
    }
    for(var i=0;i<_children.length;i++){
        if(_target==_children[i]){
            _cellGrids = getColumnArray(i,_tableCur,_target);
            var _fragment = document.createDocumentFragment();
            for(var j=0;j<_cellGrids.length;j++){
                _fragment.appendChild(_cellGrids[j]);
            }
            _tbody.appendChild(_fragment);
            _target.sortType = "asc";
        }else{
            continue;
        }
    }
}

通过给触发排序的元素th增加一个sortType的属性来标识其是否已经经过排序, 关键字可以随便取...反正是字符串.能匹配上就成.

然后在生成数组并排序的地方进行判断, 已经排序的就用倒序呈现, 没有经过排序的, 就进行正常排序.

2楼

mscript script editor + instant source + ie dev toolbar + httpwatch PK Firebug

ycliang

08-02-28 16:46 通过QQ

回复:JS版本表格排序 [ Tab...

还真是方便啊

3楼

zhaozy

08-02-28 17:02 通过网页

回复:JS版本表格排序 [ Table Sort ]

还真是方便啊
方便是挺方便的,但是JS对大型DOM Tree操作还是有点困难...

4楼

mscript script editor + instant source + ie dev toolbar + httpwatch PK Firebug
«» 4 

您还没有登录,登录后可回复帖子,