jQuery基于count和日期/时间(时间戳)对div元素进行排序

我目前使用sort函数根据计数值对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代码的外观:

 
5
1272217086
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
5
1272216786
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
10
1272299966
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

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

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

只有排序比较器function需要改变。 我确信有可用的插件,你可能想看看它们,但实现你想要的东西是相当微不足道的。 sortDescending方法每次都会获得两个div,并且比较必须遵循您指定的条件:

  1. 首先按计数
  2. 如果count相等,那么按时间戳
  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'); 

在这里查看插件的示例。

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

性能:

我强烈建议在执行sort()之前cache包装的集合。

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

这应该让sizzle /你的DOM像大时候一样rest。

要链接您的时间戳值,您还必须扩展您的排序。

 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()方法来存储日期并在排序方法中使用/访问它可能是更好的主意。