html表格排序的流程为:
    1  获取鼠标点击的 表头单元格 的列号
     
    2  遍历所有的数据行,获取每个<tr>中的html
     
    3  同时获取每个<tr>标签下对应获取到的列号的<td>标签中的内容
     
    4  并取得<th>标签的type属性值(number  string  ip)
     
    5  将获取<tr>的html、<td>的内容和<th>的type属性值拼接成字符串添加到数组array中
     
    6  然后将表格<tr>中的html全部置空
     
    7  根据type属性值的不同采用不同的方法对<td>的内容进行比较
     
    8  根据比较结果对数组array进行排序
     
    9  然后将排序后的数组元素重新赋值给已经置空的<tr>
     
    10  如果已经对该列排序过了,则直接对数组进行倒置
     
    提供数值、字符串以及IP地址三种类型的排序规则。字符串类型排序规则采用javascript的localeCompare方法。

具体代码:

<!DOCTYPE HTML>
<html> 
<head>
    <title> 表格排序 </title>
    <meta charset="utf-8">
    <meta name="Generator" content="EditPlus">
    <meta name="Author" content="tschengbin">
    <meta name="Keywords" content="jquery tableSort">
    <meta name="Description" content="">
    <script src="http://code.jquery.com/jquery-latest.js"></script>
    <style type="text/css">
        div{
            width: 1024px;
            margin: 0 auto;/*div相对屏幕左右居中*/
        }
        table{
            border: solid 1px #666;
            border-collapse: collapse;
            width: 100%;
            cursor: default;
        }
        tr{
            border: solid 1px #666;
            height: 30px;
        }
        table thead tr{
            background-color: #ccc;
        }
        td{
            border: solid 1px #666;
        }
        th{
            border: solid 1px #666;
            text-align: center;
            cursor: pointer;
        }
        .sequence{
            text-align: center;
        }
        .hover{
            background-color: #3399FF;
        }
    </style>
</head> 
<body> 
    <div>
        <table id="tableSort">
            <thead>
                <tr>
                    <th type="number">序号</th>
                    <th type="string">书名</th>
                    <th type="number">价格(元)</th>
                    <th type="string">出版时间</th>
                    <th type="number">印刷量(册)</th>
                    <th type="ip">IP</th>
                </tr>
            </thead>
            <tbody>
                <tr class="hover">
                    <td class="sequence">1</td>
                    <td>狼图腾</td>
                    <td>29.80</td>
                    <td>2009-10</td>
                    <td>50000</td>
                    <td>192.168.1.125</td>
                </tr>
                <tr>
                    <td class="sequence">2</td>
                    <td>孝心不能等待</td>
                    <td>29.80</td>
                    <td>2009-09</td>
                    <td>800</td>
                    <td>192.68.1.125</td>
                </tr>
                    <tr>
                    <td class="sequence">3</td>
                    <td>藏地密码2</td>
                    <td>28.00</td>
                    <td>2008-10</td>
                    <td></td>
                    <td>192.102.0.12</td>
                </tr>
                <tr>
                    <td class="sequence">4</td>
                    <td>藏地密码1</td>
                    <td>24.80</td>
                    <td>2008-10</td>
                    <td></td>
                    <td>215.34.126.10</td>
                </tr>
                <tr>
                    <td class="sequence">5</td>
                    <td>设计模式之禅</td>
                    <td>69.00</td>
                    <td>2011-12</td>
                    <td></td>
                    <td>192.168.1.5</td>
                </tr>
                <tr>
                    <td class="sequence">6</td>
                    <td>轻量级 Java EE 企业应用实战</td>
                    <td>99.00</td>
                    <td>2012-04</td>
                    <td>5000</td>
                    <td>192.358.1.125</td>
                </tr>
                <tr>
                    <td class="sequence">7</td>
                    <td>Java 开发实战经典</td>
                    <td>79.80</td>
                    <td>2012-01</td>
                    <td>2000</td>
                    <td>192.168.1.25</td>
                </tr>
                <tr>
                    <td class="sequence">8</td>
                    <td>Java Web 开发实战经典</td>
                    <td>69.80</td>
                    <td>2011-11</td>
                    <td>2500</td>
                    <td>215.168.54.125</td>
                </tr>
            </tbody>
        </table>
    </div>
    <script type="text/javascript">
        $(document).ready(function(){
            var tableObject = $('#tableSort');//获取id为tableSort的table对象
            var tbHead = tableObject.children('thead');//获取table对象下的thead
            var tbHeadTh = tbHead.find('tr th');//获取thead下的tr下的th
            var tbBody = tableObject.children('tbody');//获取table对象下的tbody
            var tbBodyTr = tbBody.find('tr');//获取tbody下的tr
            var sortIndex = -1; //初始化索引
            tbHeadTh.each(function() {//遍历thead的tr下的th
                var thisIndex = tbHeadTh.index($(this));//获取th所在的列号
                //鼠标移除和聚焦的效果,不重要
                $(this).mouseover(function(){ //鼠标移开事件
                    tbBodyTr.each(function(){//编列tbody下的tr
                        var tds = $(this).find("td");//获取列号为参数index的td对象集合
                        $(tds[thisIndex]).addClass("hover");
                    });
                }).mouseout(function(){ //鼠标聚焦时间
                    tbBodyTr.each(function(){
                        var tds = $(this).find("td");
                        $(tds[thisIndex]).removeClass("hover");
                    });
                });

                $(this).click(function() {  //鼠标点击事件
                    var dataType = $(this).attr("type"); //获取当前点击列的 type
                    checkColumnValue(thisIndex, dataType); //对当前点击的列进行排序 (当前索引,排序类型)
                });
            });

            //显示效果,不重要
            $("tbody tr").removeClass();//先移除tbody下tr的所有css类
            $("tbody tr").mouseover(function(){
                $(this).addClass("hover");
            }).mouseout(function(){
                $(this).removeClass("hover");
            });

            //对表格排序
            function checkColumnValue(index, type) {
                var trsValue = new Array();  //创建一个新的列表
                tbBodyTr.each(function() { //遍历所有的tr标签
                    var tds = $(this).find('td');//查找所有的 td 标签
                    //将当前的点击列 push 到一个新的列表中
                    //包括 当前行的 类型、当前索引的 值,和当前行的值
                    trsValue.push(type + ".separator" + $(tds[index]).html() + ".separator" + $(this).html());
                    $(this).html("");//清空当前列
                });
                var len = trsValue.length;//获取所有要拍戏的列的长度
                if(index == sortIndex){//sortIndex =-1
                    trsValue.reverse();//???
                } else {
                    for(var i = 0; i < len; i++){//遍历所有的行
                        type = trsValue[i].split(".separator")[0];// 获取要排序的类型
                        for(var j = i + 1; j < len; j++){
                            value1 = trsValue[i].split(".separator")[1];//当前值
                            value2 = trsValue[j].split(".separator")[1];//当前值的下一个
                            if(type == "number"){
                                //js 三元运算  如果 values1 等于 '' (空) 那么,该值就为0,否则 改值为当前值
                                value1 = value1 == "" ? 0 : value1;
                                value2 = value2 == "" ? 0 : value2;
                                //parseFloat() 函数可解析一个字符串,并返回一个浮点数。
                                //该函数指定字符串中的首个字符是否是数字。如果是,则对字符串进行解析,直到到达数字的末端为止,然后以数字返回该数字,而不是作为字符串。
                                //如果字符串的第一个字符不能被转换为数字,那么 parseFloat() 会返回 NaN。
                                if(parseFloat(value1) > parseFloat(value2)){//如果当前值 大于 下一个值
                                    var temp = trsValue[j];//那么就记住 大 的那个值
                                    trsValue[j] = trsValue[i];
                                    trsValue[i] = temp;
                                }
                            } else if(type == "ip"){
                                if(ip2int(value1) > ip2int(value2)){
                                    var temp = trsValue[j];
                                    trsValue[j] = trsValue[i];
                                    trsValue[i] = temp;
                                }
                            } else {
                                //JavaScript localeCompare() 方法 用本地特定的顺序来比较两个字符串。
                                //说明比较结果的数字。
                                // 如果 stringObject 小于 target,则 localeCompare() 返回小于 0 的数。
                                // 如果 stringObject 大于 target,则该方法返回大于 0 的数。
                                // 如果两个字符串相等,或根据本地排序规则没有区别,该方法返回 0。
                                if (value1.localeCompare(value2) > 0) {//该方法不兼容谷歌浏览器
                                    var temp = trsValue[j];
                                    trsValue[j] = trsValue[i];
                                    trsValue[i] = temp;
                                }
                            }
                        }
                    }
                }
                for(var i = 0; i < len; i++){
                    //将排序完的 值 插入到 表格中
                    //:eq(index) 匹配一个给定索引值的元素
                    $("tbody tr:eq(" + i + ")").html(trsValue[i].split(".separator")[2]);
                    //console.log($("tbody tr:eq(" + i + ")").html())
                }
                sortIndex = index;
            }
            //IP转成整型 ?????
            function ip2int(ip){
                var num = 0;
                ip = ip.split(".");
                //Number() 函数把对象的值转换为数字。
                num = Number(ip[0]) * 256 * 256 * 256 + Number(ip[1]) * 256 * 256 + Number(ip[2]) * 256 + Number(ip[3]);
                return num;
            }
            })
    </script>
</body> 
</html>


https://blog.51cto.com/yucanghai/1694691