我目前使用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代码的外观:
<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>
我想按计数(减少)排序,然后是时间戳(减少 - 最新的)。
非常感谢任何帮助!谢谢:))
答案 0 :(得分:4)
只需要更改排序比较器功能。我确信有可用的插件,你可能想看看它们,但实现你想要的东西是相当微不足道的。 sortDescending
方法每次都会获得两个div,并且比较必须遵循您指定的条件:
这是丑陋直白的非优化版本:
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');
查看plugin here的示例。
顺便说一句,这些都不会对文档本身的元素进行实际排序。有关如何执行此操作,请参阅此question。
答案 1 :(得分:1)
性能:
在强制执行cache
之前,我强烈建议sort()
包裹的内容。
var $items = $('#list .list_item');
$items.sort(sortDescending);
这应该让sizzle /你的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()
方法来存储日期并在排序方法中使用/访问它可能更好。