jQuery 根据计数和日期/时间(时间戳)对 div 元素进行排序

Lyo*_*yon 3 sorting jquery

我目前使用 sort 函数根据计数值对我的 div 元素进行排序。这是现在的做法:(我不确定这是否是一种有效的方法......)

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

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

我正在考虑添加时间戳字段,但不确定如何扩展它以支持这一点。

我有一个带有自己的计数和日期/时间/时间戳的 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>
Run Code Online (Sandbox Code Playgroud)

我想按计数(递减)排序,然后是时间戳(递减 - 最新在顶部)。

任何帮助是极大的赞赏!谢谢 :)

Anu*_*rag 5

只有排序比较器功能需要改变。我确信有可用的插件来做到这一点,你可能想看看它们,但实现你想要的东西是相当简单的。该sortDescending方法每次获取两个 div,并且比较必须遵循您指定的条件:

  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;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您看到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;
    };
}
Run Code Online (Sandbox Code Playgroud)

然后将所有条件作为回调传递给此sortBy函数。这是您的代码的粗略示例:

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

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

$("selector").sort(sortBy(compareCount, compareTimestamp));
Run Code Online (Sandbox Code Playgroud)

在我们这样做的同时,让我们也用它制作一个 jQuery 插件。它将有一个漂亮而简单的界面:

$("parent selector").sortBy("child selector 1", "child selector 2", ...);
Run Code Online (Sandbox Code Playgroud)

这个想法是传递一个 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;
};
Run Code Online (Sandbox Code Playgroud)

用于

$('#list .list_item').sortBy('.count', '.timestmap');
Run Code Online (Sandbox Code Playgroud)

此处查看插件示例。

顺便说一句,这些实际上都不会对文档本身中的元素进行排序。请参阅此问题以了解如何执行此操作。