代码之家  ›  专栏  ›  技术社区  ›  Lyon

jquery基于计数和日期/时间(时间戳)对DIV元素进行排序

  •  3
  • Lyon  · 技术社区  · 16 年前

    我目前使用sort函数根据count值对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 回复  |  直到 16 年前
        1
  •  4
  •   Community Mohan Dere    9 年前

    只有sort comparator函数需要更改。我敢肯定有插件可以实现这一点,您可能想看看它们,但是实现您想要的东西是相当琐碎的。这个 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;
        }
    }
    

    如果你看到 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;
        };
    }
    

    然后将所有条件作为回调传递给 索尔比 功能。下面是一个简单的代码示例:

    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 如何做到这一点。

        2
  •  1
  •   jAndy    16 年前

    性能:

    我强烈建议 cache 在执行 sort() .

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

    这应该给sizzle/yourddom一个像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 内容。如果动态地在某个地方生成这些节点,那么使用jquery可能是更好的主意。 $.data() 方法存储日期并在排序方法中使用/访问该日期。