jQuery сортировка элементов div на основе количества и даты / времени (отметка времени) - PullRequest
3 голосов
/ 25 июня 2010

В настоящее время я использую функцию сортировки для сортировки элементов div на основе значения счетчика. Вот как это делается сейчас: (Я не уверен, что это эффективный метод или нет ..)

$('#list .list_item').sort(sortDescending).appendTo('#list');

function sortDescending(a, b) {
  return $(a).find(".count").text() < $(b).find(".count").text() ? 1 : -1;
};

Я думаю о добавлении поля метки времени и не уверен, как его расширить, чтобы поддержать это.

У меня есть список элементов div с собственным счетчиком и датой / временем / меткой времени. Вот как будет выглядеть HTML-код:

<div id="list">
<div id="list_item_1" class="list_item">
  <div class="count">5</div>
  <div class="timestamp">1272217086</div>
  <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis quis ipsum rutrum metus rhoncus feugiat non vel orci. Etiam sit amet nisi sit amet est convallis viverra</div>
</div>
<div id="list_item_2" class="list_item">
  <div class="count">5</div>
  <div class="timestamp">1272216786</div>
  <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis quis ipsum rutrum metus rhoncus feugiat non vel orci. Etiam sit amet nisi sit amet est convallis viverra</div>
</div>
<div id="list_item_3" class="list_item">
  <div class="count">10</div>
  <div class="timestamp">1272299966</div>
  <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis quis ipsum rutrum metus rhoncus feugiat non vel orci. Etiam sit amet nisi sit amet est convallis viverra</div>
</div>
</div>

Я бы хотел отсортировать по количеству (по убыванию) с последующей отметкой времени (по убыванию - самое новое вверху).

Любая помощь очень ценится! Спасибо:)

Ответы [ 2 ]

4 голосов
/ 25 июня 2010

Необходимо изменить только функцию компаратора сортировки.Я уверен, что для этого есть плагины, и вы, возможно, захотите взглянуть на них, но реализовать то, что вы хотите, довольно тривиально.Метод sortDescending каждый раз получает два деления, и сравнение должно соответствовать заданным вами критериям:

  1. Сначала по количеству
  2. Если число равно, то по отметке времени
  3. Если временные метки равны, то вернуть 0

Вот ужасно простая неоптимизированная версия:

function sortDescending(a, b) {
    if(getCount(a) < getCount(b)) {
        return -1;
    }
    else if(getCount(a) > getCount(b)) {
        return 1;
    }
    else if(getTimestamp(a) < getTimestamp(b)) {
        return -1;
    }
    else if(getTimestamp(a) > getTimestamp(b) {
        return 1;
    }
    else {
        return 0;
    }
}

Если вы видите структуру if-else, она можетКажется очевидным, что вы можете обобщить этот подход, чтобы иметь возможность обрабатывать любые типы пользовательских заказов.Итак, вот джеб в методе sortBy, который принимает число функций обратного вызова, где каждый обратный вызов определяет один критерий сортировки.

function sortBy() {
    var callbacks = arguments;

    return function(a, b) {
        for(var i = 0; i < callbacks; i++) {
            var value = callbacks[i](a, b);
            if(value != 0) {
                return value;
            }
        }
        return 0;
    };
}

Затем передайте все критерии как обратные вызовы этой функции sortBy.Вот грубый пример для вашего кода:

function compareCount(a, b) {
    return getCount(a) - getCount(b);
}

function compareTimestamp(a, b) {
    return getTimestamp(a) - getTimestamp(b);
}

$("selector").sort(sortBy(compareCount, compareTimestamp));

И пока мы это делаем, давайте также сделаем из этого плагин jQuery.Он будет иметь приятный и простой интерфейс:

$("parent selector").sortBy("child selector 1", "child selector 2", ...);

Идея состоит в том, чтобы передать селектор jQuery, который выберет узел, текст которого будет определять значение для сортировки.Мы дадим целым числам более высокий приоритет и сначала попробуем выполнить числовую сортировку, если оба значения таковы, в противном случае проведем регулярное сравнение.

jQuery.fn.sortBy = function() {  
    var selectors = arguments;

    this.sort(function(a, b) {
        // run through each selector, and return first non-zero match
        for(var i = 0; i < selectors.length; i++) {
            var selector = selectors[i];

            var first = $(selector, a).text();
            var second = $(selector, b).text();

            var isNumeric = Number(first) && Number(second);
            if(isNumeric) {
                var diff = first - second;
                if(diff != 0) {
                    return diff;
                }
            }
            else if(first != second) {
                return first < second ? -1 : 1;
            }
        }

        return 0;
    });

    this.appendTo(this.parent());

    return this;
};

Используйте как

$('#list .list_item').sortBy('.count', '.timestmap');

См. Пример плагина здесь .

Между прочим, ничего из этого на самом деле не отсортирует элементы в самом документе.См. Этот вопрос о том, как это сделать.

1 голос
/ 25 июня 2010

Производительность:

Я бы настоятельно рекомендовал cache упакованный набор перед выполнением sort().

var $items = $('#list .list_item');
$items.sort(sortDescending);

Это должно дать шипению / твоему DOM перерыв, как bigtime.

Чтобы также связать значение вашей временной метки, вы должны расширить сортировку.

function sortDescending(a, b) {
  var a_count = parseInt((a).find(".count").text(), 10),
      b_count = parseInt((b).find(".count").text(), 10),
      a_time  = parseInt((a).find(".timestamp").text(), 10),
      b_time  = parseInt((b).find(".count").text(), 10);

  return (a_count < b_count && a_time > b_time);
};

При написании этого я действительно понял, что не буду анализировать эти значения через содержимое element. Если вы генерируете эти узлы где-то динамически, возможно, лучше использовать метод jQuerys $.data() для хранения даты и использования / доступа к ней в вашем методе сортировки.

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