表格排序实例(2-2)

表格排序

知识点

  • [ ] 引入js的顺序:要依据js之间的依赖关系,依次引入 require.js就是按需加载js

    表格排序实例

步骤

  • [x] 1、获取要操作的元素

  • [x] 2、获取后台JSON数据(Ajax)

    • 1) 创建Ajax对象
    • 2) 打开请求数据地址
    • 3) 监听请求状态
    • 4) 发送请求
  • [x] 3、数据绑定

  • [x] 4、隔行变色

  • [x] 5、表格排序

  • [x] 6、点击排序


代码分析

  • [x] 1、获取要操作的元素

    1
    2
    3
    4
    5
    var tab = document.getElementById("tab");
    var tHead = tab.tHead;
    var tHcell = tHead.rows[0].cells;
    var tBody = tab.tBodies[0];
    var tBrow = tBody.rows;
  • [x] 2、首先获取后台(data.txt)中数据(JSON格式的字符串)->Ajax(async js and xml)

    • 1) 创建Ajax对象

      1
      var xhr = new XMLHttpRequest;
    • 2) 打开请求数据地址

      1
      xhr.open("get", "data.txt", false); //false为同步,只有这四步完成之后才能继续执行
    • 3) 监听请求状态

      1
      2
      3
      4
      5
      6
      7
      8
      xhr.onreadystatechange = function() {
      if (xhr.readyState === 4 && /^2\d{2}$/.test(xhr.status)) {
      var val = xhr.responseText;
      // console.log(val);显示请求数据(JSON字符串)
      data = utils.jsonParse(val); // 将请求的数据转换为JSON对象格式
      // console.log(data);// 以JSON对象的格式显示请求的数据
      }
      };
    • 4) 发送请求

      1
      xhr.send(null);
  • [x] 3、数据绑定

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    function bind() {
    var frg = document.createDocumentFragment();
    for (var i = 0; i < data.length; i++) {
    var cur = data[i];
    var newtr = document.createElement("tr");
    for (var key in cur) { //cur有几个键值对就创建几个td
    var newtd = document.createElement("td");
    //判断性别
    if (key === "sex") {
    newtd.innerHTML = cur[key] === 0 ? "男" : "女"; //得到的是对应key的值
    } else {
    newtd.innerHTML = cur[key];
    }
    newtr.appendChild(newtd);
    }
    frg.appendChild(newtr);
    }
    tBody.appendChild(frg);
    frg = null;
    }
  • [x] 4、隔行变色

    1
    2
    3
    4
    5
    function changeBg() {
    for (var i = 0; i < tBrow.length; i++) {
    tBrow[i].className = i % 2 === 1 ? "bg" : null;
    }
    }
  • [x] 5、表格排序

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    function sort(n) { //n是当前点击这一列的索引
    var _this = this;//this-->tHcell[n]
    //把存储所有行的类数组转换为数组
    var arr = utils.listToArray(tBrow);
    //优化:点击当前列,需让其他列的flag存储的值回归到初始化值-1(为了返回点击其他列时,按默认的排序)
    for(var k=0;k<tHcell.length;k++){
    if(tHcell[k]!==this){
    tHcell[k].flag=-1;
    }
    }
    //数组排序:按每一行的第二列的内容升序
    _this.flag *= -1; //每次执行sort,第一步先让flag*-1;
    arr.sort(function(a, b) {
    // this-->window,所以下面的tHcell[1]不能简单换成this
    var curA=a.cells[n].innerHTML;
    var curB=b.cells[n].innerHTML;
    var curAnum=parseFloat(a.cells[n].innerHTML);
    var curBnum=parseFloat(b.cells[n].innerHTML);
    if(isNaN(curAnum)||isNaN(curBnum)){//isNaN判断参数是否“不是数值”
    return curA.localeCompare(curB)* _this.flag;
    }else{
    return (curAnum-curBnum)* _this.flag;
    }
    //只考虑数值,未考虑字母或汉字的排序
    // return (parseFloat(a.cells[n].innerHTML) - parseFloat(b.cells[n].innerHTML)) * _this.flag
    });
    //按新数组顺序添加到页面tBody
    var frg = document.createDocumentFragment();
    for (var i = 0; i < arr.length; i++) {
    frg.appendChild(arr[i]);
    }
    tBody.appendChild(frg);
    frg = null;
    //按照最新的顺序,实现隔行变色
    changeBg();
    }
  • [x] 6、点击排序

    • [ ] 点击第二列实现排序

      1
      2
      3
      4
      5
      6
      7
      tHcell[1].flag=-1;//给当前点击这一列增加自定义属性flag,存储的值为1;
      tHcell[1].onclick=function(){
      // this->tHcell[1]
      // sort();//->sort中的this->window;
      sort.call(this);//或sort.call(tHcell[1]);//->sort中的this->tHcell[1];
      }
    • [ ] 点击实现排序(所有具有class=”cursor”这个样式的列都可以实现排序)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      for (var i = 0; i < tHcell.length; i++) {
      var curth = tHcell[i];
      if (curth.className === "cursor") {
      curth.index = i; //用来存储索引
      curth.flag = -1; //用来实现升降序
      curth.onclick = function() {
      sort.call(this, this.index);
      }
      }
      }

引用附件

  • [ ] 加载JSON数据

    1
    2
    3
    [
    {"name":"li","age":24,"score":98,"sex":0}, {"name":"lia","age":23,"score":99,"sex":1}, {"name":"lie","age":25,"score":98,"sex":1}, {"name":"liw","age":28,"score":78,"sex":0}, {"name":"life","age":24,"score":98,"sex":1}, {"name":"liu","age":29,"score":100,"sex":0}, {"name":"lih","age":20,"score":98,"sex":1}, {"name":"lil","age":21,"score":89,"sex":0}
    ]
  • [ ] 公有方法js文件(先引入该js文件)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    var utils = {
    listToArray: function(likeArray) {
    var arr = [];
    try {
    arr = [].slice.call(likeArray);
    } catch (e) {
    for (var i = 0; i < likeArray.length; i++) {
    arr[arr.length] = likeArray[i];
    }
    }
    return arr;
    },
    jsonParse: function(str) {
    var val = null;
    try {
    return JSON.parse(str);
    } catch (e) { //兼容IE6-8
    //一定要记住手动加小括号
    return eval("(" + jsonstr + ")");
    }
    //或者
    // return "JSON" in window ? JSON.parse(str) : eval("(" + jsonstr + ")");
    }
    }
  • [ ] 逻辑思路tab.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    // ->操作谁就先获取谁
    var tab = document.getElementById("tab");
    var tHead = tab.tHead;
    var tHcell = tHead.rows[0].cells;
    var tBody = tab.tBodies[0];
    var tBrow = tBody.rows;
    var data = null;//请求的数据对象
    //->1、首先获取后台(data.txt)中数据(JSON格式的字符串)->Ajax(async js and xml)
    //1)创建一个Ajax对象
    var xhr = new XMLHttpRequest;
    //2)打开需要请求的数据文件地址
    xhr.open("get", "data.txt", false); //false为同步,只有这四步完成之后才能继续执行
    //3)监听请求状态
    xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && /^2\d{2}$/.test(xhr.status)) {
    var val = xhr.responseText;
    // console.log(val);显示请求数据(JSON字符串)
    data = utils.jsonParse(val); // 将请求的数据转换为JSON对象格式
    // console.log(data);// 以JSON对象的格式显示请求的数据
    }
    };
    //4)发送请求
    xhr.send(null);
    //->2、实现数据绑定(文档碎片的方式)
    function bind() {
    var frg = document.createDocumentFragment();
    for (var i = 0; i < data.length; i++) {
    var cur = data[i];
    var newtr = document.createElement("tr");
    // newtr.innerHTML="<td>"+cur.name+"</td>"+"<td>"+cur.age+"</td>"+"<td>"+cur.score+"</td>"+"<td>"+cur.sex+"</td>";
    for (var key in cur) { //cur有几个键值对就创建几个td
    var newtd = document.createElement("td");
    //判断性别
    if (key === "sex") {
    newtd.innerHTML = cur[key] === 0 ? "男" : "女"; //得到的是对应key的值
    } else {
    newtd.innerHTML = cur[key];
    }
    newtr.appendChild(newtd);
    }
    frg.appendChild(newtr);
    }
    tBody.appendChild(frg);
    frg = null;
    }
    bind();
    //3、实现隔行变色
    function changeBg() {
    for (var i = 0; i < tBrow.length; i++) {
    tBrow[i].className = i % 2 === 1 ? "bg" : null;
    }
    }
    changeBg();
    //4、表格排序:按年龄排序
    function sort(n) { //n是当前点击这一列的索引
    var _this = this;//this-->tHcell[n]
    //把存储所有行的类数组转换为数组
    var arr = utils.listToArray(tBrow);
    //优化:点击当前列,需让其他列的flag存储的值回归到初始化值-1(为了返回点击其他列时,按默认的排序)
    for(var k=0;k<tHcell.length;k++){
    if(tHcell[k]!==this){
    tHcell[k].flag=-1;
    }
    }
    //数组排序:按每一行的第二列的内容升序
    _this.flag *= -1; //每次执行sort,第一步先让flag*-1;
    arr.sort(function(a, b) {
    // this-->window,所以下面的tHcell[1]不能简单换成this
    var curA=a.cells[n].innerHTML;
    var curB=b.cells[n].innerHTML;
    var curAnum=parseFloat(a.cells[n].innerHTML);
    var curBnum=parseFloat(b.cells[n].innerHTML);
    if(isNaN(curAnum)||isNaN(curBnum)){//isNaN判断参数是否“不是数值”
    return curA.localeCompare(curB)* _this.flag;
    }else{
    return (curAnum-curBnum)* _this.flag;
    }
    //只考虑数值,未考虑字母或汉字的排序
    // return (parseFloat(a.cells[n].innerHTML) - parseFloat(b.cells[n].innerHTML)) * _this.flag
    });
    //按新数组顺序添加到页面tBody
    var frg = document.createDocumentFragment();
    for (var i = 0; i < arr.length; i++) {
    frg.appendChild(arr[i]);
    }
    tBody.appendChild(frg);
    frg = null;
    //按照最新的顺序,实现隔行变色
    changeBg();
    }
    //5、点击第二列实现排序
    tHcell[1].flag=-1;//给当前点击这一列增加自定义属性flag,存储的值为1;
    tHcell[1].onclick=function(){
    // this->tHcell[1]
    // sort();//->sort中的this->window;
    sort.call(this);//或sort.call(tHcell[1]);//->sort中的this->tHcell[1];
    }
    //5、点击实现排序(所有具有class="cursor"这个样式的列都可以实现排序)
    for (var i = 0; i < tHcell.length; i++) {
    var curth = tHcell[i];
    if (curth.className === "cursor") {
    curth.index = i; //用来存储索引
    curth.flag = -1; //用来实现升降序
    curth.onclick = function() {
    sort.call(this, this.index);
    }
    }
    }