Сортировка продолжает сдвигать строки, когда есть 11+ строк - PullRequest
0 голосов
/ 28 декабря 2011

См. Код в ссылках jsfiddle, приведенных ниже

Существует множество способов сортировки таблицы с использованием javascript (+ jquery). Я начал использовать плагин сортировки jquery Джеймса Падолси. Мне пришлось изменить его демонстрационный код, поскольку он не проверял равенство (он проверял только больше и меньше).

Все работает нормально, пока в таблице не будет 11+ строк и 3 строки не будут одинаковыми. 3 ряда продолжали сдвигаться после каждой сортировки. Вы можете попробовать это здесь ; продолжайте нажимать на «Fruit» и заметьте, что «яблочные» ряды смещаются. Если вы удалите одну из строк таблицы, смещение и остановка сортировки будут правильными.

Я начал проверять, могу ли я написать собственную сортировку и использовать сортировку массива js, и столкнулся с той же проблемой. Вы можете поиграть с ним здесь . Обратите внимание, что я сортирую только по первому столбцу и по возрастанию каждый раз, когда вы щелкаете заголовок таблицы. Каждый раз поднимаясь, он все еще сдвигает «яблочные» ряды.

Похоже, что это проблема сортировки массива Javascript (поскольку плагин Джеймса тоже его использует)? У кого-нибудь есть идеи по этому поводу или я делаю это неправильно?

Ответы [ 3 ]

0 голосов
/ 28 декабря 2011

Из исходного кода jQuery 1.7:

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

Вместо этого попробуйте что-то вроде решения Джеймса Падолси :

/**
 * 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));
        });

    };

})();
0 голосов
/ 28 декабря 2011

Я закончил сортировку других столбцов, если текущие данные, которые я сортирую, равны. Я также решил изменить демо-код Джеймса, чтобы поддержать это (не его код плагина). 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;
    }
}
0 голосов
/ 28 декабря 2011

Затем вы хотите отсортировать по нескольким столбцам. 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/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...