当行数超过11行时,排序会保持移位行

时间:2011-12-27 20:35:10

标签: javascript jquery sorting

请参阅下面提供的jsfiddle链接中的代码

有很多方法可以使用javascript(+ jquery)对表进行排序。我开始使用James Padolsey的jquery排序插件。我不得不修改他的演示代码,因为它没有检查是否相等(它只是检查更大和更少)。

一切正常,直到表中有11行以及行中的3行相同。每排后3排都在移动。 You can try it out here;继续点击“水果”,注意“苹果”行正在转移。如果您移除其中一个表格行,则换档停止和排序是正确的。

我开始看看我是否可以编写自己的排序并使用js数组排序,我遇到了同样的问题。 You can play with it here。请注意,我每次只按第一列排序,每次单击表标题时都按升序排序。 每次上升,它仍在移动“苹果”行。

看来这是一个Javascript数组排序问题(因为James'插件也在使用它)?任何人对此有任何想法或我做错了吗?

3 个答案:

答案 0 :(得分:0)

然后,您希望对多个列进行排序。 JavaScript没有做任何你没有告诉它的事情。

$('th').click(function(){
    var header = $(this);
    // only sorting the by the 1st column (for now) and in ascending only
    header.closest('table').find('tbody tr').sort(function(a, b) {
        var compA = $(a).find('td:first-child').text().toUpperCase();
        var compB = $(b).find('td:first-child').text().toUpperCase();
        var compC = +$(a).find('td:first-child').next().text();
        var compD = +$(b).find('td:first-child').next().text();

        if(compA < compB) { 
            return -1;
        }
        else if(compA > compB) {
            return 1;
        }
        else if(compC < compD) { 
            return -1;
        }
        else if(compC > compD) {
            return 1;
        }
        else {
            return 0;
        }
    }).appendTo(header.closest('table')); 
});

http://jsfiddle.net/mblase75/hQ7NK/4/

答案 1 :(得分:0)

来自jQuery 1.7的源代码:

// For internal use only.
// Behaves like an Array's method, not like a jQuery method.
sort: [].sort,

相反,请尝试James Padolsey's solution

/**
 * jQuery.fn.sortElements
 * --------------
 * http://james.padolsey.com/javascript/sorting-elements-with-jquery/
 * @param Function comparator:
 *   Exactly the same behaviour as [1,2,3].sort(comparator)
 *   
 * @param Function getSortable
 *   A function that should return the element that is
 *   to be sorted. The comparator will run on the
 *   current collection, but you may want the actual
 *   resulting sort to occur on a parent or another
 *   associated element.
 *   
 *   E.g. $('td').sortElements(comparator, function(){
 *      return this.parentNode; 
 *   })
 *   
 *   The <td>'s parent (<tr>) will be sorted instead
 *   of the <td> itself.
 */
jQuery.fn.sortElements = (function(){

    var sort = [].sort;

    return function(comparator, getSortable) {

        getSortable = getSortable || function(){return this;};

        var placements = this.map(function(){

            var sortElement = getSortable.call(this),
                parentNode = sortElement.parentNode,

                // Since the element itself will change position, we have
                // to have some way of storing its original position in
                // the DOM. The easiest way is to have a 'flag' node:
                nextSibling = parentNode.insertBefore(
                    document.createTextNode(''),
                    sortElement.nextSibling
                );

            return function() {

                if (parentNode === this) {
                    throw new Error(
                        "You can't sort elements if any one is a descendant of another."
                    );
                }

                // Insert before flag:
                parentNode.insertBefore(this, nextSibling);
                // Remove flag:
                parentNode.removeChild(nextSibling);

            };

        });

        return sort.call(this, comparator).each(function(i){
            placements[i].call(getSortable.call(this));
        });

    };

})();

答案 2 :(得分:0)

如果我正在排序的当前数据相等,我最后会对其他列进行排序。我还决定修改James的演示代码来支持这个(不是他的插件代码)。 http://jsfiddle.net/C8nQ2/1/

下面的递归函数支持2列以上的表。它将通过列进行排序,如果等于,则继续到下一列,等等。

function calc(a, b, first) {
    var valueA = $(a).text(),
        valueB = $(b).text();

    if(valueA == valueB) {
        // 1st time calling & sort is not on 1st column so sort the first by column
        if(first && (index != 0)) {
            return calc(a.parent().children().eq(0), b.parent().children().eq(0));
        }

        // no more columns to sort, both rows are exactly the same
        if(a.index() == th.length - 1) { 
            return 0; 
        }

        // sort by the next column
        return calc(a.next(), b.next());
    } else {
        return (isNaN(valueA) || isNaN(valueB) ? valueA > valueB : +valueA > +valueB) ? inverse ? -1 : 1 : inverse ? 1 : -1;
    }
}