Many component libraries now include tables with sorting capabilities. We’ve been around the front end for a long time, but we’ve been using these wheels all the time, and we haven’t implemented sorting. Yesterday when I was doing the test, I came across such a table sorting problem. I had no idea at all. So I did a lot of research.

First, basic HTML

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <title>Document</title>
</head>
<body>
    <div class="container">
        <table>
            <thead>
                <tr><th>ID</th><th>Commodity codes</th><th>The price</th></tr>
            </thead>
            <tbody>
                <tr><td>1</td><td>60006</td><td>22</td></tr>
                <tr><td>2</td><td>20002</td><td>11</td></tr>
                <tr><td>3</td><td>30003</td><td>66</td></tr>
                <tr><td>4</td><td>10001</td><td>33</td></tr>
                <tr><td>5</td><td>50005</td><td>44</td></tr>
                <tr><td>6</td><td>40004</td><td>55</td></tr>
            </tbody>
        </table>
    </div>
    <script src="./index.js"></script>

</body>
</html>
Copy the code

The container class in the body contains a simple table with three columns of data: ID, barcode, and price. Now click on the table header to sort the table in ascending or descending order. In code language, you sort the row elements by adding a click event to the table header element.

Js implementation is as follows:

const order = {
    init (param) {
        const that = this;
        const table = param.el;
        if(! table)return;
        // Get the tbody node
        const tbody = table.getElementsByTagName('tbody') [0];
        // Get all th nodes and convert them to arrays
        const ths = Array.from(table.getElementsByTagName('th'));
        // Get all tr nodes and convert them to arrays
        const trs = Array.from(tbody.getElementsByTagName('tr'));
        const list = this.getBodyList(trs);
        ths.forEach((th, index) = > {
            // Bind the click event for th
            th["addEventListener"] ('click'.() = > {
                // Check whether the current data is in ascending order
                const isAsc = this.isAsc(list, index);
                // Sort the list in descending order if it is currently in ascending order; If currently in descending order, sort the list in ascending order;
                list.sort((a, b) = > isAsc ? b.value[index]- a.value[index]: a.value[index] - b.value[index]);
                // Insert the sorted list back into tbody
                list.forEach((tr, index) = > {
                    tbody.appendChild(tr.tr)
                });
            });
        });
    },
    getBodyList (trs) {
        console.log(trs)
        return trs.map(tr= > {
            // Get all td nodes of tr and convert them to arrays
            const tds = Array.from(tr.getElementsByTagName('td'));
            // Convert td contents to numbers
            const val = tds.map(td= > parseInt(td.innerHTML));
            return {tr: tr, value: val};
        });
    },
    isAsc (list, index) {
        // Check whether the index of the list value is in ascending order
        let arr = list.map(tr= > tr.value[index])
        let flag = true;
        for(let i=0; i<arr.length - 1; i++){
            if(arr[i] > arr[i+1]){
                flag = false;
                break; }}returnflag; }}; order.init({// Obtain the node of the table under class=container
    el: document.getElementsByClassName('container') [0].getElementsByTagName('table') [0]});Copy the code

Points to note:

  • GetElementsByTagName returnsHTMLCollectionClass array type data, cannot be used as an array type directly, but can be passedArray.from()Convert to an array
  • To determine whether the current order is in ascending order, extract the column of data to be determined first
  • Sort function sort if yesa - bIt’s sort of in ascending order,b - aIt’s in descending order
  • When appendChild inserts an existing node, it actually moves the node, so you don’t have to worry about having two identical TR nodes