5

I have a TODO list app with an Unordered list. Within it I have a few list items. The li classes are high,medium,low. I would like li's with the class high to be placed before li's with the class medium and last ones with low.

<ul id="tasks">
  <li id="item3" class="priority low"><span></span><a href="#" class="closex" onclick="removeItem('item3')"></a><span>This is a low priority task</span></li>
  <li id="item4" class="priority high"><></span><a href="#" class="closex" onclick="removeItem('item4')"></a><span>This is a high priority task</span></li>
  <li id="item5" class="priority low"><span></span><a href="#" class="closex" onclick="removeItem('item5')"></a><span>This is another Low</span></li>
  <li id="item7" class="priority medium"><span></span><a href="#" class="closex" onclick="removeItem('item7')"></a><span>And now a Medium</span></li>
</ul>

So the li with id of item4 should be first and then it should be item7 and then the li's with class low after.

4

6 に答える 6

3

Here's a pure JS version of @ŠimeVidas jQuery solution.

var tasks = document.querySelector('#tasks'),
    items = document.querySelectorAll('#tasks > li');

for (var i = 0, arr = ['high', 'medium', 'low']; i < arr.length; i++) {
    for (var j = 0; j < items.length; j++) {
        if (~(" " + items[j].className + " ").indexOf(" " + arr[i] + " "))
            tasks.appendChild(items[j]);
    }
}
于 2012-11-02T01:03:21.470 に答える
0

純粋なJavaScriptとシンプルなコードで!

var tasks = document.getElementById("tasks");
var lis = tasks.getElementsByTagName("li");
var lisarr = Array.prototype.slice.call(lis);

var priority = function(e){
    var prio = {low: 0, medium: 1, high: 2};
    return prio[e.getAttribute("class").match(/low|high|medium/)[0]];
};

lisarr.sort(function(a,b){
    var ap = priority(a), bp = priority(b);
    return bp - ap;
});

tasks.innerHTML = lisarr.reduce(function(prev, current){
    return prev + current.outerHTML;
}, '');
于 2012-11-02T01:07:30.703 に答える
0

Assuming you can use jQuery, and assuming your list is not very big, and assuming you've only got these three fixed types with no plans on changing this, I'd probably just dump the whole set into memory, clear out the list, then put them back in the list in order. Something like:

jQuery(document).ready(function() {
    var i;
    var items = jQuery("#tasks li");
    var lowItems = [];
    var medItems = [];
    var highItems = [];
    for (i = 0; i < items.length; ++i) {
        var jqItem = jQuery(items[i]);
        if (jqItem.hasClass("low")) lowItems.push(jqItem);
        if (jqItem.hasClass("medium")) medItems.push(jqItem);
        if (jqItem.hasClass("high")) highItems.push(jqItem);
    }
    var tasks = jQuery("#tasks");
    tasks.html("");
    for (i = 0; i < highItems.length; ++i) {
        tasks.append(highItems[i]);
    }   
    for (i = 0; i < medItems.length; ++i) {
        tasks.append(medItems[i]);
    }   
    for (i = 0; i < lowItems.length; ++i) {
        tasks.append(lowItems[i]);
    }
});
于 2012-11-01T23:57:34.290 に答える
0

Try this:

$(function(){
    var sorter = [],
        tasks = $('#tasks');
    $('li.priority').each(function(){
        var $this = $(this),
            priority = $this.hasClass('high') ? 3 : ($this.hasClass('medium') ? 2 : 1);
        sorter.push({
            el : this,
            priority : priority
        });
    }).detach();

    sorter.sort(function(a, b){
        return a.priority - b.priority;
    });

    $.each(sorter, function(){
        tasks.append(this.el);
    });
});
于 2012-11-02T00:02:21.757 に答える
0

With no jquery:

<ul id="tasks">
 <li id="item3" class="priority low"><span></span><a href="#" class="closex" onclick="removeItem('item3')"></a><span>This is a low priority task</span></li>
 <li id="item4" class="priority high"><></span><a href="#" class="closex" onclick="removeItem('item4')"></a><span>This is a high priority task</span></li>
 <li id="item5" class="priority low"><span></span><a href="#" class="closex" onclick="removeItem('item5')"></a><span>This is another Low</span></li>
 <li id="item7" class="priority medium"><span></span><a href="#" class="closex" onclick="removeItem('item7')"></a><span>And now a Medium</span></li>
</ul>

<script type="text/javascript">
var tasks = document.getElementById("tasks");
var liElements = tasks.getElementsByTagName("li");
var lowPriority = [];
var mediumPriority = [];
var highPriority = [];
var removal = [];
for (var i = 0, len = liElements.length; i < len; i++) {
    if (liElements[i].getAttribute("class").indexOf("low") > -1) lowPriority.push(liElements[i].cloneNode(true));
    if (liElements[i].getAttribute("class").indexOf("medium") > -1) mediumPriority.push(liElements[i].cloneNode(true));
    if (liElements[i].getAttribute("class").indexOf("high") > -1) highPriority.push(liElements[i].cloneNode(true));
    removal.push(liElements[i]);
}

for (var i = 0, len = removal.length; i < len; i++ ) {
    var liItem = removal[i];
    liItem.parentNode.removeChild(liItem);
}

for( var i = 0, len = lowPriority.length; i < len; i++){
    tasks.appendChild(lowPriority[i]);
}
for (var i = 0, len = mediumPriority.length; i < len; i++) {
    tasks.appendChild(mediumPriority[i]);
}
for (var i = 0, len = highPriority.length; i < len; i++) {
    tasks.appendChild(highPriority[i]);
}
</script>
于 2012-11-02T00:06:12.860 に答える
0

Here's another jQuery–less option:

// Just a helper
function toArray(obj) {
  var result = [];
  for (var i=0, iLen=obj.length; i<iLen; i++) {
    result[i] = obj[i];
  }
  return result;
}

// Uses querySelectorAll, but could use getElementsByTagName instead
function sortByPriority(id) {
  var nodes;
  var el = document.getElementById(id);

  if (el) { 
    nodes = toArray(el.querySelectorAll('li.priority'));
    nodes.sort(function(a, b) {
      function getIndex(el) {
        return el.className.indexOf('low') != -1? 1 : 
               el.className.indexOf('medium') != -1? 2 :
               el.className.indexOf('high') != -1? 3 :
               0; // default
      }
      return getIndex(b) - getIndex(a);
    });

    for (var i=0, iLen=nodes.length; i<iLen; i++) {
      el.appendChild(nodes[i]);
    }
  }
}

It uses a few more lines that a jQuery (or perhaps any library) based solution but you don't have to load several thousand lines of library either.

Also, this runs about 5 times faster in Firefox and IE 9 and 10 times faster in Chrome than a jQuery solution (see http://jsperf.com/sortelementlist).

于 2012-11-02T00:47:58.670 に答える