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

这是@ŠimeVidas jQuery 解决方案的纯 JS 版本。

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

这是另一个没有 jQuery 的选项:

// 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]);
    }
  }
}

它比基于 jQuery(或任何库)的解决方案多使用了几行,但您也不必加载数千行库。

此外,它在 Firefox 和 IE 9 中的运行速度比 jQuery 解决方案快 5 倍,在 Chrome 中快 10 倍(参见http://jsperf.com/sortelementlist)。

于 2012-11-02T00:47:58.670 回答
0

假设您可以使用 jQuery,并且假设您的列表不是很大,并且假设您只有这三种固定类型而没有计划更改它,我可能只是将整个集合转储到内存中,清除列表,然后将它们按顺序放回列表中。就像是:

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

没有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

尝试这个:

$(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

使用纯 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 回答