jquery排序函数和prepend / insertAfter?

时间:2017-06-09 02:59:27

标签: javascript jquery sorting

我有一个功能,可以根据列表项的日期和类对列表项进行排序。已经很晚了,我很累,也很沮丧,所以不确定我在这里缺少什么。

该函数应首先确定该类是否为.pinned并按日期对它们进行排序,然后将它们插入列表的顶部。

然后它应该查看项目的日期(在data-date中找到),如果它早于今天,则添加类.past按日期排序,然后在固定项之后插入它们。

最后,它应该对剩余的项目进行排序,并在最后一个项目.past

之后插入它们

这是代码:

//sort todo list-items by type and then date
function sortTodo() {
  var itemDate = "";
  var date = new Date();
  $(".todo-list-item").each(function() {
    var itemDate = new Date($(this).data("date"));
    if($(this).hasClass('pinned')) {
      $(".todo-list-item.pinned").sort(function(a,b) {
        return date > itemDate;
      }).each(function() {
          $(".todo-list").prepend(this);
      })
    } else if(date > itemDate) {
      $(this).addClass("past");
      $(".todo-list-item.past").sort(function(a,b) {
          return date > itemDate;
      }).each(function() {
          $(".todo-list").prepend(this);
      })
    } else {
      $(".todo-list-item").not(".pinned, .past").sort(function(a,b) {
        return date > itemDate;
      }).each(function() {
          $(".todo-list").append(this);
      })
    }
  });
}

$(document).ready(function() {
    sortTodo();
});

CODE PEN DEMO

截至目前,脚本没有根据需要将固定项目放在顶部,除非我添加了一个新的固定项目,并且在项目类更改或删除后没有按日期排序。

2 个答案:

答案 0 :(得分:1)

首页加载时固定项目不在待办事项列表顶部的原因是因为它是列表中第一个被添加到待办事项列表前面的项目。

当页面加载时,第一个项目被固定,因此它会被添加到列表中。然后它继续循环遍历列表,直到找到其日期>的项目。 itemDate并将放在固定项目之前。

要了解我的意思:尝试通过将固定项目作为无序列表中的最后一项来更改您的html。

*抱歉 - 我没有足够的代表发表评论......

答案 1 :(得分:1)

您的代码每个项目(!)在三个单独的步骤中对元素进行排序和移动。这会弄乱整体结果的顺序。

只需排序一次并一个接一个地附加排序列表的不同部分(jQuery .filter()对此有用)。当您通过时,所有物品都将被重新订购。

关于Array#sort的注意事项:当您返回truefalse时,它不起作用。它希望你返回小于,等于或大于0的数字。幸运的是,相互减去日期会给你这些数字。

以下内容对页面上所有列表中的所有项目进行排序。

// helper
function appendToParent() { this.parentNode.appendChild(this); }

$(function() {
  var $items = $(".todo-list-item").sort(function(a, b) {
    return new Date($(a).data("date")) - new Date($(b).data("date"));
  });

  // append items by priority
  $items.filter(".pinned").each(appendToParent);
  $items.filter(".pinned.past").each(appendToParent);
  $items.filter(":not(.pinned)").each(appendToParent);
  $items.filter(":not(.pinned).past").each(appendToParent);
});
.past { font-style: italic; }
.pinned { color: red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

List 1
<ul class="todo-list">
  <li class="todo-list-item past" data-date="2017-05-03">Past Item 5</li>
  <li class="todo-list-item" data-date="2017-06-04">Item 4</li>
  <li class="todo-list-item pinned" data-date="2017-06-02">Item 1 (pinned)</li>
  <li class="todo-list-item" data-date="2017-06-03">Item 3</li>
  <li class="todo-list-item pinned past" data-date="2017-05-03">Past Item 2 (Pinned)</li>
</ul>

List 2
<ul class="todo-list">
  <li class="todo-list-item past" data-date="2017-05-03">Past Item 5</li>
  <li class="todo-list-item" data-date="2017-06-04">Item 4</li>
  <li class="todo-list-item pinned" data-date="2017-06-02">Item 1 (pinned)</li>
  <li class="todo-list-item" data-date="2017-06-03">Item 3</li>
  <li class="todo-list-item pinned past" data-date="2017-05-03">Past Item 2 (Pinned)</li>
</ul>

切换.past类也很容易,但是我已经将它从上面的示例代码中删除了,因为在将来的某些时候,这里的所有项目最终都会“过去”,这将无视示例代码的目的。

$items.each(function () {
  $(this).toggleClass("past", new Date( $(this).data("date") ) < Date.now());
});