admin管理员组

文章数量:1128409

I'm a bit out of my depth here and I'm hoping this is actually possible.

I'd like to be able to call a function that would sort all the items in my list alphabetically.

I've been looking through the jQuery UI for sorting but that doesn't seem to be it. Any thoughts?

I'm a bit out of my depth here and I'm hoping this is actually possible.

I'd like to be able to call a function that would sort all the items in my list alphabetically.

I've been looking through the jQuery UI for sorting but that doesn't seem to be it. Any thoughts?

Share Improve this question edited Oct 15, 2010 at 19:30 Shog9 159k36 gold badges235 silver badges240 bronze badges asked Jul 16, 2009 at 1:20 dougoftheabacidougoftheabaci 2
  • 7 stackoverflow.com/questions/304396/… – gen_Eric Commented Oct 15, 2010 at 19:33
  • Check out Underscore.js or Sugar.js. – Kris Khaira Commented Mar 1, 2012 at 14:21
Add a comment  | 

10 Answers 10

Reset to default 352

Something like this:

var mylist = $('#myUL');
var listitems = mylist.children('li').get();
listitems.sort(function(a, b) {
   return $(a).text().toUpperCase().localeCompare($(b).text().toUpperCase());
})
$.each(listitems, function(idx, itm) { mylist.append(itm); });

From this page: http://www.onemoretake.com/2009/02/25/sorting-elements-with-jquery/

Above code will sort your unordered list with id 'myUL'.

OR you can use a plugin like TinySort. https://github.com/Sjeiti/TinySort

You do not need jQuery to do this...

function sortUnorderedList(ul, sortDescending) {
  if(typeof ul == "string")
    ul = document.getElementById(ul);

  // Idiot-proof, remove if you want
  if(!ul) {
    alert("The UL object is null!");
    return;
  }

  // Get the list items and setup an array for sorting
  var lis = ul.getElementsByTagName("LI");
  var vals = [];

  // Populate the array
  for(var i = 0, l = lis.length; i < l; i++)
    vals.push(lis[i].innerHTML);

  // Sort it
  vals.sort();

  // Sometimes you gotta DESC
  if(sortDescending)
    vals.reverse();

  // Change the list on the page
  for(var i = 0, l = lis.length; i < l; i++)
    lis[i].innerHTML = vals[i];
}

Easy to use...

sortUnorderedList("ID_OF_LIST");

Live Demo →

$(".list li").sort(asc_sort).appendTo('.list');
//$("#debug").text("Output:");
// accending sort
function asc_sort(a, b){
    return ($(b).text()) < ($(a).text()) ? 1 : -1;    
}

// decending sort
function dec_sort(a, b){
    return ($(b).text()) > ($(a).text()) ? 1 : -1;    
}

live demo : http://jsbin.com/eculis/876/edit

To make this work work with all browsers including Chrome you need to make the callback function of sort() return -1,0 or 1.

see http://inderpreetsingh.com/2010/12/01/chromes-javascript-sort-array-function-is-different-yet-proper/

function sortUL(selector) {
    $(selector).children("li").sort(function(a, b) {
        var upA = $(a).text().toUpperCase();
        var upB = $(b).text().toUpperCase();
        return (upA < upB) ? -1 : (upA > upB) ? 1 : 0;
    }).appendTo(selector);
}
sortUL("ul.mylist");

If you are using jQuery you can do this:

$(function() {

  var $list = $("#list");

  $list.children().detach().sort(function(a, b) {
    return $(a).text().localeCompare($(b).text());
  }).appendTo($list);

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<ul id="list">
  <li>delta</li>
  <li>cat</li>
  <li>alpha</li>
  <li>cat</li>
  <li>beta</li>
  <li>gamma</li>
  <li>gamma</li>
  <li>alpha</li>
  <li>cat</li>
  <li>delta</li>
  <li>bat</li>
  <li>cat</li>
</ul>

Note that returning 1 and -1 (or 0 and 1) from the compare function is absolutely wrong.

@SolutionYogi's answer works like a charm, but it seems that using $.each is less straightforward and efficient than directly appending listitems :

var mylist = $('#list');
var listitems = mylist.children('li').get();

listitems.sort(function(a, b) {
   return $(a).text().toUpperCase().localeCompare($(b).text().toUpperCase());
})

mylist.empty().append(listitems);

Fiddle

improvement based on Jeetendra Chauhan's answer

$('ul.menu').each(function(){
    $(this).children('li').sort((a,b)=>a.innerText.localeCompare(b.innerText)).appendTo(this);
});

why i consider it an improvement:

  1. using each to support running on more than one ul

  2. using children('li') instead of ('ul li') is important because we only want to process direct children and not descendants

  3. using the arrow function (a,b)=> just looks better (IE not supported)

  4. using vanilla innerText instead of $(a).text() for speed improvement

  5. using vanilla localeCompare improves speed in case of equal elements (rare in real life usage)

  6. using appendTo(this) instead of using another selector will make sure that even if the selector catches more than one ul still nothing breaks

I was looking to do this myself, and I wasnt satisfied with any of the answers provided simply because, I believe, they are quadratic time, and I need to do this on lists hundreds of items long.

I ended up extending jquery, and my solution uses jquery, but could easily be modified to use straight javascript.

I only access each item twice, and perform one linearithmic sort, so this should, I think, work out to be a lot faster on large datasets, though I freely confess I could be mistaken there:

sortList: function() {
   if (!this.is("ul") || !this.length)
      return
   else {
      var getData = function(ul) {
         var lis     = ul.find('li'),
             liData  = {
               liTexts : []
            }; 

         for(var i = 0; i<lis.length; i++){
             var key              = $(lis[i]).text().trim().toLowerCase().replace(/\s/g, ""),
             attrs                = lis[i].attributes;
             liData[key]          = {},
             liData[key]['attrs'] = {},
             liData[key]['html']  = $(lis[i]).html();

             liData.liTexts.push(key);

             for (var j = 0; j < attrs.length; j++) {
                liData[key]['attrs'][attrs[j].nodeName] = attrs[j].nodeValue;
             }
          }

          return liData;
       },

       processData = function (obj){
          var sortedTexts = obj.liTexts.sort(),
              htmlStr     = '';

          for(var i = 0; i < sortedTexts.length; i++){
             var attrsStr   = '',
                 attributes = obj[sortedTexts[i]].attrs;

             for(attr in attributes){
                var str = attr + "=\'" + attributes[attr] + "\' ";
                attrsStr += str;
             }

             htmlStr += "<li "+ attrsStr + ">" + obj[sortedTexts[i]].html+"</li>";
          }

          return htmlStr;

       };

       this.html(processData(getData(this)));
    }
}

Put the list in an array, use JavaScript's .sort(), which is by default alphabetical, then convert the array back to a list.

http://www.w3schools.com/jsref/jsref_sort.asp

HTML

<ul id="list">
    <li>alpha</li>
    <li>gamma</li>
    <li>beta</li>
</ul>

JavaScript

function sort(ul) {
    var ul = document.getElementById(ul)
    var liArr = ul.children
    var arr = new Array()
    for (var i = 0; i < liArr.length; i++) {
        arr.push(liArr[i].textContent)
    }
    arr.sort()
    arr.forEach(function(content, index) {
        liArr[index].textContent = content
    })
}

sort("list")

JSFiddle Demo https://jsfiddle.net/97oo61nw/

Here we are push all values of li elements inside ul with specific id (which we provided as function argument) to array arr and sort it using sort() method which is sorted alphabetical by default. After array arr is sorted we are loop this array using forEach() method and just replace text content of all li elements with sorted content

本文标签: javascriptHow may I sort a list alphabetically using jQueryStack Overflow