0

我有以下代码可以使用 Javascript 对表格进行排序。我想要做的是将表格的最后一行作为总计,因此需要附加我的代码以从排序中删除最后一行。我在完成这项任务时遇到了麻烦。

var TableSort = function ( tableId ) {
    var that = this;

    // Store a reference to the table node as a property
    this.table = document.getElementById(tableId);

    // Validate the table node
    if ( this.table && this.table.nodeType != 1 ) {
        throw new Error("TableSort: Table id is not a DOM element.");
    }
    if ( this.table.tagName != "TABLE" ) {
        throw new Error("TableSort: Table id is not a table element.");
    }

    // Set three global properties
    this.sortColumn = "";
    this.sortUp = true;
    this.imageNodes = [];


    // Get the header nodes
    var headers = this.table.getElementsByTagName("th");

    // Loop through the header nodes
    var header, columnName, imageNode, imageClick;
    for ( var i = 0; i < headers.length; i++) {
        header = headers[i];

        // Create a node for the image
        imageNode = document.createElement("img");

        // Add the "sort arrow" images to the header column
        // And set the first column as the default sort column
        columnName = header.className;
        if ( i == 0 ) {
            this.sortColumn = columnName;
            imageNode.src = "arrows_up.png";
        } else {
            imageNode.src = "arrows_off.png";
        }

        // Get the event handler for the image
        imageClick = this.imageClickHandler(columnName);

        // Add the event handler to the image
        jsLib.event.add(imageNode, "click", imageClick);

        // Add the image node to column header and to array of image nodes
        header.appendChild(imageNode);
        this.imageNodes[columnName] = imageNode;
    }

    // Sort the table
    this.sort();
}

TableSort.prototype.imageClickHandler = function (columnName) {
    var that = this;

    // return an event handler
    return function () {
        // If current sort column, toggle the sort direction
        if ( that.sortColumn == columnName ) {
            that.sortUp = ! that.sortUp;
        // Otherwise...
        } else {
            // Set the image for the old sort column
            that.imageNodes[that.sortColumn].src = "arrows_off.png";

            // Switch the current sort column and sort ascending
            that.sortColumn = columnName;
            that.sortUp = true;
        }

        // Set the appropriate arrows for the current sort column
        if ( that.sortUp ) {
            that.imageNodes[that.sortColumn].src = "arrows_up.png";
        } else {
            that.imageNodes[that.sortColumn].src = "arrows_down.png";
        }

        that.sort();
    }
}

TableSort.prototype.sort = function () {
    var that = this;
    if ( this.sortColumn == "" ) return;

    // Get the rows from the table
    var rowNodes = this.table.getElementsByTagName("tr");
    if (rowNodes.length <= 1 ) return;

    // Store a reference to each row in the rows array
    var rows = [];
    for ( var i = 0; i < rowNodes.length; i++) {
        rows.push( rowNodes[i] );
    }

    // Get a reference to the tbody node
    var tbodyNode = rows[0].parentNode;

    // Remove the header row from the array (but not the DOM)
    rows.shift();



    // Remove all rows except the header row from the DOM
    var row;
    for ( i = 0; i < (rows.length); i++ ) {
        row = rows[i];
        row.parentNode.removeChild(row);
    }   

    // Define two functions that check for data types
    var isMoney = function ( value ) {
        var m = value.replace( /[$,]/g, "" );
        return ! isNaN(m);
    }
    var isDate = function ( value ) {
        var d = new Date(value);
        return ! isNaN(d);
    }

    // Define the direction variable
    var direction = ( that.sortUp ) ? 1 : -1;

    // Define the function that compares the rows
    var compareColumnValues = function (rowA, rowB) {
        var valueA, valueB;
        var i, cell;

        // Get the cell value for row A
        var cellsA = rowA.getElementsByTagName("td");
        for ( i = 0; i < cellsA.length; i++ ) {
            cell = cellsA[i];
            if ( cell.className == that.sortColumn ) {
                valueA = cell.firstChild.nodeValue;
                break;
            }
        }

        // Get the cell value for row B
        var cellsB = rowB.getElementsByTagName("td");
        for ( i = 0; i < cellsB.length; i++ ) {
            cell = cellsB[i];
            if ( cell.className == that.sortColumn ) {
                valueB = cell.firstChild.nodeValue;
                break;
            }
        }

        // Convert the values to the appropriate data type
        if ( ! isNaN(valueA) && ! isNaN(valueB) ) {
            valueA = parseFloat(valueA);
            valueB = parseFloat(valueB);
        } else if ( isDate(valueA) && isDate(valueB) ) {
            valueA = new Date(valueA);
            valueB = new Date(valueB);
        } else if ( isMoney(valueA) && isMoney(valueB) ) {
            valueA = parseFloat(valueA.replace( /[$,]/g, "" ));
            valueB = parseFloat(valueB.replace( /[$,]/g, "" ));
        }

        // Compare the two values and return the appropriate comparison value
        if ( valueA < valueB ) {
            return -1 * direction;
        } else if ( valueB < valueA ) {
            return 1 * direction;
        } else {
            return 0;
        }
    }

    // Use the compareColumnValues function to sort the rows array
    rows.sort( compareColumnValues );

    // Add all rows back to the DOM
    for ( i = 0; i < rows.length; i++) {
        tbodyNode.appendChild( rows[i] );
    }
}
4

2 回答 2

4

您可以在 HTML 标记中使用更多结构来帮助您的代码确定可以排序的内容。

将总计行放在一个tfoot元素中,将可排序的行放在一个tbody元素中......现在您可以定位可排序的行,例如

var sortableRows = this.table.getElementsByTagName('tbody'),
    rowNodes = sortableRows.getElementsByTagName('tr');

更新:由于您无法更改标记,请从排序数组中删除最后一行并将其缓存。

...
// Remove the header row from the array (but not the DOM)
rows.shift();
// And now we remove the footer row and cache it
var footerRow = rows.pop();

然后修改您的代码以使用insertBefore

...
// Add all rows back to the DOM, before the footer row
for ( i = 0; i < rows.length; i++) {
    tbodyNode.insertBefore(rows[i], footerRow);
}

该循环实际上是一个性能问题,因为您正在对 DOM 进行多次写入。最好将所有这些排序的节点写入 adocumentFragment并只写入一次 DOM,如下所示:

...
var sortedFragment = document.createDocumentFragment();

// Write all the sorted rows to a fragment
for ( i = 0; i < rows.length; i++) {
    sortedFragment.appendChild(rows[i]);
}

// Insert fragment containing sorted rows before footer
tbodyNode.insertBefore(sortedFragment, footerRow);
于 2013-04-23T00:17:11.763 回答
2

我找到了一个很好的解决方案,我实际上在我的工作代码中使用了它!然而,我不能把功劳归于它,但我只是想为你们指出正确的方向:

http://www.kryogenix.org/code/browser/sorttable/

"1.在这里下载Javascript库:http ://www.kryogenix.org/code/browser/sorttable/sorttable.js

2.包含 Javascript 库,方法是在页面的 HEAD 中放置一个指向它的链接,如下所示:

3.通过给它一个“可排序”类将你的表标记为可排序的:

请注意,该库的 JavaScript 文件称为 sorttable(两个 T),但您添加到表中的类是可排序的(一个 T)。”

设置非常简单,应该允许升序和降序排序。如果您有任何问题,请告诉我。

谢谢!保罗

于 2013-11-19T13:28:23.690 回答