• 欢迎访问开心洋葱网站,在线教程,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入开心洋葱 QQ群
  • 为方便开心洋葱网用户,开心洋葱官网已经开启复制功能!
  • 欢迎访问开心洋葱网站,手机也能访问哦~欢迎加入开心洋葱多维思维学习平台 QQ群
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏开心洋葱吧~~~~~~~~~~~~~!
  • 由于近期流量激增,小站的ECS没能经的起亲们的访问,本站依然没有盈利,如果各位看如果觉着文字不错,还请看官给小站打个赏~~~~~~~~~~~~~!

JavaScript对表格或者元素按照文本,数字或者日期排序

JavaScript 水墨上仙 2297次浏览

JavaScript对表格或者元素按照文本,数字或者日期排序

// Sorting table columns correctly by text, number or date. There are other 
// versions, plugins, etc., for this but they either are restricted to specific 
// date formats, or require EVERY row-element to be given a sort attribute; mine 
// can handle many different date and number formats, and even allows for specific 
// cells that may not conform to the overall date/number format for that column. 
// My version also enables sorting of element hierarchies: such as a DIV containing 
// P-paragraphs and SPANs - this could even be an image-gallery containing prices 
// or dates within spans. Very efficient as well!!
// Example: andrew.dx.am/sortgallerydel.html
// AddSortToTables(); will make the table headers clickable, to sort columns in 
// ascending or descending order, for any tables with class="sortIt".
// SortTable(tbl, col); will sort the table (tbl is an id or table object) by 
// the supplied column index (indexed from 0) in ascending or descending order.
//
// AddSortByDate(tbl, col, dateMask); enables sorting of a column by date, 
// specified by a date-mask such as 'dd-mmm-yy'.
// AddSortByNumber(tbl, col); enables sorting of a column by number. This assumes a 
// period . as the decimal separator (if present); it ignores any other non-numeric 
// characters.
//
// SortElements(parentEl, childTag, colTag, colIndex); will sort (non-table) 
// elements in ascending or descending order. For example, an UL containing LIs 
// and SPANs. colIndex specifies which span to sort; there may be more than one in 
// the LI (0 indexed).
// Example: SortElements('divid', 'p', 'span', 2); // 3rd span within each paragraph.
//
// AddSortByDate2(parentEl, childTag, colTag, colIndex, dateMask); and 
// AddSortByNumber2(parentEl, childTag, colTag, colIndex)
// provide the same feature-set as AddSortByDate and AddSortByNumber does 
// for tables, but for element hierarchies.
// If there are dates or numbers in a column (or element) which don't meet the 
// date-mask or number formatting necessary to sort correctly, then these individual 
// elements can be given the attribute "sort" and they will still sort correctly!
// For example, with a date column <td sort="2012/12/20"> will still sort a 
// cell correctly. (This format 'YYYY/MM/DD' will be converted into a Date() object.)
var MonthNames = ["January", "February", "March", "April", "May", "June", "July", 
    "August", "September", "October", "November", "December"];
var DayNames = [ "Sunday", "Monday", "Tueday", "Wednesday", "Thursday", 
    "Friday", "Saturday" ];
var ShortMths = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", 
    "Sep", "Oct", "Nov", "Dec"];
var ShortDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
var AddEvent = function (elem, eventType, func) {
    // Helper function.
    if ( elem.addEventListener )
        AddEvent = function (elem, eventType, func) {
            elem.addEventListener(eventType, func, false);
        };
    else if ( elem.attachEvent )
        AddEvent = function (elem, eventType, func) {
            elem.attachEvent('on' + eventType, func);
        };
    else
        AddEvent = function (elem, eventType, func) {
            elem['on' + eventType] = func;
        };
    AddEvent(elem, eventType, func);
};
// Sort methods/algorithms attributed:
// A Gibson http://andrew.dx.am
var SortTable = function (tbl, col) {
    // could be called directly
    SortElements(tbl, 'tr', 'td', col);
};
var SortElements = function (parentEl, childTag, colTag, colIndex) {
    // example use: SortElements('table1','tr','td',2)
    // or SortElements('list1','li')
    // or SortElements('divName','p','span',3)
    var i, j, cTags = {}, startAt = 0, childLen, aChild, elem,
        sortBy, content, elems = [], sortedLen, frag, hdrsLen, hdr;
    var parent = (typeof parentEl === 'string') ? 
        document.getElementById(parentEl) : parentEl;
    var AscText = function (a, b) {     // sort() by .data as text
        var x = a.data, y = b.data,
            xNum = parseFloat(x), yNum = parseFloat(y);
            // check if each begin with a number..
        if ( !isNaN(xNum) && !isNaN(yNum) && (xNum - yNum) )
            return xNum - yNum;
        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
    };
    var DescText = function (a, b) {        // sort() by .data
        var x = a.data, y = b.data,
            xNum = parseFloat(x), yNum = parseFloat(y);
            // check if each begin with a number..
        if ( !isNaN(xNum) && !isNaN(yNum) && (yNum - xNum) )
            return yNum - xNum;
        return ((x > y) ? -1 : ((x < y) ? 1 : 0));
    };
    var AscNum = function (a, b) {  // used with dates as well
        return a.data - b.data;
    };
    var DescNum = function (a, b) {
        return b.data - a.data;
    };
    if (parent.nodeName.toLowerCase() == 'table') {
        if ( childTag == 'tr' ) {
            sortBy = parent.rows[0].cells[colIndex].sortBy || 'text';
        }
        parent = parent.tBodies[0] || parent;
        if ( parent.rows[0].cells[0].nodeName.toLowerCase() == 'th' ) {
            startAt = 1;
        }
    }
    cTags = parent.getElementsByTagName(childTag);
    if ( typeof colIndex == 'undefined' ) {
        sortBy = 'text';    // sort simple lists or paragraphs as text
    }
    for (i = startAt, childLen = cTags.length; i < childLen; i++) {
        // ..go forward examining each child
        aChild = cTags[i];
        elem = (colTag) ? aChild.getElementsByTagName(colTag)[colIndex] : aChild;
        if (elem) {
            if ( !sortBy ) {        // sorting non-table columns..
                sortBy = (typeof elem.numberValue != 'undefined') ? 'number' : 
                    ((typeof elem.dateValue != 'undefined') ? 'date' : 'text');
            }
            switch (sortBy) {
            // You can supply 'sort' attributes to enable sorting of numbers, etc.
            // For example, <td sort='2011/02/12'> for a date.
                case 'text':
                    content = (elem.getAttribute('sort') || 
                        elem.firstChild.nodeValue).toLowerCase();
                    break;
                case 'number':
                    content = elem.numberValue;
                    break;
                case 'date':
                    content = elem.dateValue;
                    break;
                default:
                    content = (elem.getAttribute('sort') || 
                        elem.firstChild.nodeValue).toLowerCase();
                    break;
            }
            j = elems.length;
            if ( !aChild.id ) 
                aChild.id = 'tempSortID' + j;
            elems[j] = { data: content, tempID: aChild.id };
        }
    }
    // The following will determine if the table/etc has already been sorted 
    // by the same column or tag. If so, it will sort in ascending or descending 
    // order. It creates custom element properties to the parent element to 
    // remember the previous sort details.
    if ( typeof colIndex == 'undefined' ) colIndex = 0;
    if ( parent.prevTag && parent.prevTag == ((typeof colTag == 'undefined') ? 
            childTag : colTag) ) {
        if (parent.prevCol == colIndex) {
            // sorting by the same column as previously
            parent.prevSort = (parent.prevSort == 'asc') ? 'desc' : 'asc';
        } else {                            // sorting by any other column
            parent.prevCol = colIndex;
            parent.prevSort = 'asc';
        }
    } else {
        // sorting for the 1st time or by a different tag
        parent.prevTag = ((typeof colTag == 'undefined') ? childTag : colTag);
        parent.prevCol = colIndex;
        parent.prevSort = 'asc';
    }
    if ( parent.prevSort === 'desc' ) {
        // 'desc' WILL BE the previous sort order..
        switch (sortBy) {
            case 'text': elems.sort(DescText); break;
            case 'number': elems.sort(DescNum); break;
            case 'date': elems.sort(DescNum); break;
            default: elems.sort(DescText); break;
        }
    } else {
        switch (sortBy) {
            case 'text': elems.sort(AscText); break;
            case 'number': elems.sort(AscNum); break;
            case 'date': elems.sort(AscNum); break;
            default: elems.sort(AscText); break;
        }
    }
    frag = document.createDocumentFragment();
    for (i = 0, sortedLen = elems.length; i < sortedLen; i++) {
        elem = document.getElementById(elems[i].tempID);
        frag.appendChild(elem);
        if ( (elem.id).substr(0,10) == 'tempSortID' )
            elem.removeAttribute('id');
    }
    parent.appendChild(frag);
    elems = null;
    return parent.prevSort;     // not currently used
};
var AddSortToTables = function () {
    // ..if table has class-name 'sortIt'
    var tables = document.getElementsByTagName('table'), i, j, 
        tblLen, tbl, hdrs, hdrsLen;
    function PreserveSortScope(a,b,c,d) {
        return function () {
            // assign the SortElements fn. to a table header
            SortElements(a, b, c, d);
        }
    }
    // add sorting to table headers
    for ( i = 0, tblLen = tables.length; i < tblLen; i++ ) { 
        tbl = tables[i];
        if ( tbl.className.indexOf('sortIt') + 1) {
            hdrs = tbl.getElementsByTagName('th');
            if ( hdrs ) {
                for ( j = 0, hdrsLen = hdrs.length; j < hdrsLen; j++ ) {
                    AddEvent(hdrs[j],'click',PreserveSortScope(tbl,'tr','td',j));
                    // if there's no title already, add "Click to sort"
                    if ( !hdrs[j].title ) hdrs[j].setAttribute('title',
                        'Click to sort');
                }
            }
        }
    }
};
var AddSortByDate = function (tbl, col, dateMask) {
    // Input: the table name (or object), a column index (or array) 
    // and a date mask ('dd-mmm-yy')
    // Adds a sortBy = 'date' property to the first row
    // will ignore the first row, assuming it is a header row
    var i, rLen, cell;
    while ( col.length ) AddSortByDate(tbl,col.pop(),dateMask);
    if ((col instanceof Array) || isNaN(col)) return;
    var tbl = (typeof tbl === 'string') ? document.getElementById(tbl) : tbl;
    tbl.rows[0].cells[col].sortBy = 'date';
    AddSortByDate2(tbl, 'tr', 'td', col, dateMask);
};
var AddSortByDate2 = function (parentEl, childTag, colTag, colIndex, dateMask) {
    var kids, startAt = 0, i, rLen, cell;
    var parent = (typeof parentEl === 'string') ? 
        document.getElementById(parentEl) : parentEl;
    if ( parent.nodeName.toLowerCase() == 'table' ) {
        parent = parent.tBodies[0] || parent;
        startAt = ( parent.rows[0].cells[0].nodeName.toLowerCase() == 'th' ) * 1;
    }
    kids = parent.getElementsByTagName(childTag);
    for ( i = startAt, rLen =  kids.length; i < rLen; i++) {
        cell = kids[i].getElementsByTagName(colTag)[colIndex];
        if (cell) {
            if ( typeof cell.numberValue != 'undefined' ) delete cell.numberValue;
            // the above enables switching from a number to a date sort 
            // (although v. unlikely)
            if (cell.getAttribute('sort')) {
                // use sort attribute if present
                cell.dateValue = new Date(cell.getAttribute('sort'));
            } else {
                cell.dateValue = new Date(StringToDate(cell.firstChild.nodeValue, 
                    dateMask));
            }
            if (cell.dateValue.toString() == "NaN" || cell.dateValue.toString() == 
                    "Invalid Date") {
                cell.dateValue = 0;
            } 
        }
    }
};
var AddSortByNumber = function (tbl, col) {
    // col is a column index or array of indices
    // will ignore the first row, assuming it is a header row
    var i, rLen, cell, tempNum;
    while ( col.length ) AddSortByNumber(tbl,col.pop());
    if ((col instanceof Array) || isNaN(col)) return;
    tbl = (typeof tbl === 'string') ? document.getElementById(tbl) : tbl;
    tbl.rows[0].cells[col].sortBy = 'number';
    AddSortByNumber2(tbl,'tr','td',col);
};
var AddSortByNumber2 = function (parentEl, childTag, colTag, colIndex) {
    var kids, startAt = 0, i, rLen, cell, tempNum;
    var parent = (typeof parentEl === 'string') ? 
        document.getElementById(parentEl) : parentEl;
    if ( parent.nodeName.toLowerCase() == 'table' ) {
        parent = parent.tBodies[0] || parent;
        startAt = (parent.rows[0].cells[0].nodeName.toLowerCase() == 'th') * 1;
    }
    kids = parent.getElementsByTagName(childTag);
    for (i = startAt, rLen = kids.length; i < rLen; i++) {
        cell = kids[i].getElementsByTagName(colTag)[colIndex];
        if (cell) {
            if ( typeof cell.dateValue != 'undefined' ) delete cell.dateValue;
            // the above enables switching from a date to a number sort
            // (although v. unlikely)
            tempNum = cell.getAttribute('sort') || cell.firstChild.nodeValue;
            tempNum = tempNum.replace(/[^0-9.-]/g, '');
            cell.numberValue = parseFloat(tempNum);
            if (isNaN(cell.numberValue)) 
                cell.numberValue = 0.0;
        }
    }
};
var StringToDate = function (sDate, sFormat, cutOff) {
    // Input: a date value as a string, it's format as a string e.g. 'dd-mmm-yy'
    // Optional: a cutoff (integer) for 2 digit years.
    // If no 'd' appears in the format string then the 1st of the month is assumed.
    // If the year is 20 and the cut-off is 30 then the value will be converted 
    // to 2020; if the year is 40 then this will be converted to 1940.
    // If no cut-off is supplied then '20' will be pre-pended to the year (YY).
    // Output: a string in the format 'YYYY/MM/DD' or ''
    // Will not attempt to convert certain combinations e.g. DMM, MDD, DDM, YYYYD.
    var sParsed, fndSingle;
    // sParsed will be constructed in the format 'YYYY/MM/DD'
    sDate = sDate.toString().toUpperCase();
    sFormat = sFormat.toUpperCase();
    
    if (sFormat.search(/MMMM|MMM/) + 1) {       // replace Mar/March with 03, etc.
        sDate = sDate.replace(new RegExp('(' + ShortMths.join('|') + ')[A-Z]*', 'gi'),
            function (m) {
            var i = ShortMths.indexOf(m.charAt(0).toUpperCase() + 
                m.substr(1, 2).toLowerCase()) + 1;
            return ((i < 10) ? "0" + i : "" + i).toString();
        });
        sFormat = sFormat.replace(/MMMM|MMM/g, 'MM');
    }
    if (sFormat.search(/DDDD|DDD/) + 1) {       // replace Tue/Tuesday, etc. with ''
        sDate = sDate.replace(new RegExp('(' + ShortDays.join('|') + ')[A-Z]*', 'gi'),'');
        sFormat = sFormat.replace(/DDDD|DDD/g, '');
    }
    sDate = sDate.replace(/(^|\D)(\d)(?=\D|$)/g, function($0, $1, $2) {
        // single digits 2 with 02
        return $1 + '0' + $2;
    });
    sFormat = sFormat.replace(/(^|[^DMY])(D|M)(?=[^DMY]|$)/g, function($0, $1, $2){
        return $1 + $2 + $2;        // replace D or M with DD and MM
    });
    // are there still single Ds or Ms?
    fndSingle = sFormat.search(/(^|[^D])D([^D]|$)|(^|[^M])M([^M]|$)/)+1;
    if ( fndSingle ) return '';     // do not attempt to parse, for example, 'DMM'
    sFormat = sFormat.replace(/(^|[^Y])(YY)(?=[^Y]|$)/g, function($0, $1, $2, index) {
        var tempDate = sDate.substr(0, index + 1);
        tempDate += (cutOff) ? ((parseInt(sDate.substr(index + 1, 2),10) > cutOff) ? 
            '19' : '20') : '20';
        tempDate += sDate.substr(index + 1);
        sDate = tempDate;
        return $1 + $2 + $2;
    });
    sParsed = ('YYYY/MM/DD').replace(/YYYY|MM|DD/g, function(m){
        return (sFormat.indexOf(m) + 1) ? 
            sDate.substr(sFormat.indexOf(m), m.length) : '';
    });
    if (sParsed.charAt(0) == '/') {
        // if no year specified, assume the current year
        sParsed = (new Date().getFullYear()) + sParsed;
    }
    if (sParsed.charAt(sParsed.length - 1) == '/') {
        // if no date, assume the 1st of the month
        sParsed += '01';
    }
    // should end up with 10 characters..
    return ( sParsed.length == 10 ) ? sParsed : '';
};


开心洋葱 , 版权所有丨如未注明 , 均为原创丨未经授权请勿修改 , 转载请注明JavaScript对表格或者元素按照文本,数字或者日期排序
喜欢 (0)
加载中……