SOURCE

console 命令行工具 X clear

                    
>
console
var data = [{
  id: 1,
  title: 'test1',
  content: 'test conent2'
}, {
  id: 2,
  title: 'test3',
  content: 'test conent4'
}, {
  id: 3,
  title: 'test2',
  content: 'test conent1'
}, {
  id: 4,
  title: 'test4',
  content: 'test conent3'
}];

(function(jQuery) {
	
  jQuery.fn.sortableTable = function(data) {
    this.each(function(index, table) {
      var state = false;
      initialTable(table, data);
      table.querySelector('thead > tr').addEventListener('click', function(e) {
        let parent = e.target;
        while(parent.nodeName.toUpperCase() !== 'TH') {
          parent = parent.parentNode;
        }
        sort(table, parent.cellIndex+1, (state = !state));
        changeIcon(table, parent, state)
      }, false);
    });
  }
	
  function changeIcon(table, th, state) {
  	var ths = table.querySelectorAll('thead > tr > th');
    ths.forEach(function(thTmp) {
      if (thTmp !== th) {
        thTmp.querySelector('i').classList.remove('inc');
        thTmp.querySelector('i').classList.remove('desc');
      }
      else {
        th.querySelector('i').classList.add(state?'desc':'inc');
        th.querySelector('i').classList.remove(state?'inc':'desc');
      }
    });
  }

  function initialTable(mytable, data) {
    var thead = document.createElement('thead'),
        tbody = document.createElement('tbody');

    // thead
    var headtr = document.createElement('tr');
    for (let header in data[0]) {
      let text = document.createTextNode(header),
          i = document.createElement('i'),
          th = document.createElement('th');
      i.classList.add('sort');
      th.appendChild(text);
      th.appendChild(i);
      headtr.appendChild(th);
    }
    thead.appendChild(headtr);

    let oldHead = mytable.querySelector('thead')
    oldHead ? mytable.replaceChild(thead, oldHead) : mytable.appendChild(thead);

    //tbody
    data.forEach(function(record) {
      var bodytr = document.createElement('tr');
      for (let key in record) {
        let text = document.createTextNode(record[key]),
          td = document.createElement('td');
        td.appendChild(text);
        bodytr.appendChild(td);
      }
      tbody.appendChild(bodytr);
    });
    let oldBody = mytable.querySelector('tbody')
    oldBody ? mytable.replaceChild(tbody, oldBody) : mytable.appendChild(tbody);
    mytable.appendChild(tbody);
  }


  function sort(table, key, inc) {
    var tbody = table.querySelector('tbody'),
        trs = Array.from(tbody.querySelectorAll('tr'));
    trs.sort(function(a, b) {
      return b.querySelector(`td:nth-of-type(${key})`).innerHTML.localeCompare(a.querySelector(`td:nth-of-type(${key})`).innerHTML) * (inc ? 1 : -1);
    });
    var newBody = document.createElement('tbody');
    trs.forEach(function(tr) {
      newBody.appendChild(tr);
    });
    table.replaceChild(newBody ,tbody);
  }
  
})(jQuery);


$('#mytable').sortableTable(data);
<table id="mytable"></table>
* {
  box-sizing:border-box;
}
body {
    font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
    font-size: 14px;
    line-height: 1.42857143;
    color: #333;
}
table {
  border-spacing: 0;
  border: 1px solid #ddd;
}
td,th {
    padding: 8px;
    line-height: 1.42857143;
    vertical-align: top;
    
}
td {
	border-top: 1px solid #ddd;  
}
th {
  cursor: pointer;
}
.sort {
  position:relative;
  left:3px;
}
.sort::before,.sort::after {
  content: '';
  position:relative;
  display:inline-block;
  border:5px solid rgba(0,0,0,0);
  box-sizing:content-box;
  width:0;
  height:0;
}
.sort::before {
  top:-6px;
  border-bottom-color:#000;
}
.sort::after {
  top: 6px;
  left:-10px;
  border-top-color:#000;
}
.sort.desc::before {
  border-bottom-color:rgba(0, 0, 0, 0.2);
}
.sort.inc::after {
  border-top-color:rgba(0, 0, 0, 0.2);
}

本项目引用的自定义外部资源