2017-06-09 2 views
1

Ich habe eine Funktion zum Sortieren von Elementen basierend auf dem Datum und der Klasse des Listenelements. Es ist spät und ich bin müde und frustriert, also nicht sicher, was ich hier vermisse.jquery Sortierfunktion und prepend/insertAfter?

Die Funktion sollte zuerst feststellen, ob die Klasse .pinned ist und sie nach Datum sortieren und sie an den Anfang der Liste einfügen.

Dann sollte es auf das Datum des Artikels (in Datendatum gefunden) und wenn es früher als heute ist, fügen Sie die Klasse .past sortieren sie nach Datum, und fügen Sie sie nach den festgelegten Elemente.

Schließlich sollte es die restlichen Elemente sortieren und nach dem letzten Element mit der Klasse von .past

hier einfügen ist der Code:

//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

ab jetzt Das Skript platziert keine gepinnten Elemente nicht wie gewünscht nach oben, es sei denn, ich füge ein neues angeheftetes Element hinzu und sortiert nicht nach Datum, nachdem eine Elementklasse geändert oder entfernt wurde.

+0

Was ist das Ergebnis, wenn Sie eine Aufgabe gleichzeitig ausführen? – guest271314

+1

Wenn Sie meinen, dass jede Bedingung ohne die anderen ausgeführt wird, werden sie korrekt sortiert und fixiert –

Antwort

1

Der Grund, dass das gepinnte Element nicht ganz oben auf der Liste der Todos beim Laden der ersten Seite steht, ist, dass es das erste Element in Ihrer Liste ist, das der Todo-Liste vorangestellt wird.

Wenn die Seite geladen wird, wird das erste Element angeheftet, sodass es der Liste vorangestellt wird. Dann durchläuft es die Liste so lange, bis es die Elemente findet, deren Datum> itemDate ist, und setzt es vor das gepinnte Element.

Um zu sehen, was ich meine: Versuchen Sie, ändern Sie Ihre HTML, indem Sie das angeheftete Element als das letzte Element in Ihrer ungeordneten Liste.

* Sorry - ich habe nicht genug rep haben einen Kommentar zu hinterlassen ...

1

Der Code ist das Sortieren und Elemente in drei separaten Schritten einmal pro Stück bewegt (!). Dies verwirrt die Reihenfolge des Gesamtergebnisses.

Sortieren Sie einfach einmal und hängen Sie verschiedene Abschnitte der sortierten Liste nacheinander an (jQuery .filter() ist dafür nützlich). Wenn Sie fertig sind, werden alle Artikel neu sortiert.

Hinweis zu Array#sort: Es funktioniert nicht, wenn Sie true oder false zurückgeben. Es erwartet, dass Sie Zahlen kleiner als, gleich oder größer als 0 zurückgeben. Zum Glück gibt das Subtrahieren von Daten voneinander Ihnen genau diese Arten von Zahlen.

Im Folgenden werden alle Elemente in allen Listen auf der Seite sortiert.

// 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>

die .past Klasse Makel ist einfach, auch, aber ich habe in der Zukunft irgendwann, weil es aus dem Beispielcode oben links hier alle Elemente enden würden „vorbei zu sein ", die dem Zweck des Beispielcodes widersprechen würde.

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