我如何使用jQuery按字母顺序排序一个列表?

我有点力不从心,我希望这是可能的。

我希望能够调用一个函数,该函数将按字母顺序对列表中的所有项进行排序。

我一直在寻找通过jQuery UI排序,但这似乎不是它。任何想法吗?

321842 次浏览

就像这样:

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

来自本页:http://www.onemoretake.com/2009/02/25/sorting-elements-with-jquery/

以上代码将使用id 'myUL'对无序列表进行排序。

或者你也可以使用TinySort这样的插件。https://github.com/Sjeiti/TinySort

你做需要jQuery来做这个…

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

易于使用…

sortUnorderedList("ID_OF_LIST");

Live Demo &rarr

$(".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;
}

现场演示:http://jsbin.com/eculis/876/edit

为了使这个工作在包括Chrome在内的所有浏览器中工作,你需要使sort()的回调函数返回-1、0或1。

看到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");

我想自己做这件事,我对提供的任何答案都不满意,因为我相信,它们是二次时间,而我需要在数百个项目的列表上做这件事。

我最终扩展了jquery,和我的解决方案使用 jquery,但可以很容易地修改使用直接javascript。

我只访问每个条目两次,并执行一次线性排序,所以我认为,这应该在大型数据集上工作得更快,尽管我坦率地承认我可能错了:

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

@SolutionYogi的答案很有魅力,但似乎使用$。这两种方法都不如直接添加列表来得直接和有效:

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);

小提琴

如果你正在使用jQuery,你可以这样做:

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

注意,从比较函数是完全错误的返回1和-1(或0和1)。

将列表放入数组中,使用JavaScript的.sort()(默认为字母顺序),然后将数组转换回列表。

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

超文本标记语言

<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演示https://jsfiddle.net/97oo61nw/

这里,我们将li元素的所有值与特定的id(我们作为函数参数提供)一起推入到数组arr中,并使用sort ()方法对其排序,该方法默认按字母顺序排序。数组arr排序后,我们使用forEach ()方法循环该数组,并将所有li元素的文本内容替换为排序内容

基于Jeetendra Chauhan的答案的改进

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

为什么我认为这是一个进步:

  1. 使用each来支持在多个ul上运行

  2. 使用children('li')而不是('ul li')是很重要的,因为我们只想处理直接的子对象而不是后代对象

  3. 使用箭头函数(a,b)=>看起来更好(IE不支持)

  4. 使用香草innerText代替$(a).text()来提高速度

  5. 使用vanilla localeCompare在元素相等的情况下提高速度(在现实生活中很少使用)

  6. 使用appendTo(this)而不是使用另一个选择器将确保即使选择器捕捉到多个ul仍然没有破坏