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

时间:2010-06-25 07:04:41

标签: jquery sorting

我目前使用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>

我想按计数(减少)排序,然后是时间戳(减少 - 最新的)。

非常感谢任何帮助!谢谢:))

2 个答案:

答案 0 :(得分:4)

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

  1. 首先计算
  2. 如果count相等,则按时间戳
  3. 如果时间戳相等,则返回0
  4. 这是丑陋直白的非优化版本:

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

相关问题