Я тут трохи не в глибині, і сподіваюся, що це насправді можливо.
Мені б хотілося викликати функцію, яка б сортувала всі елементи мого списку за алфавітом.
Я переглядав інтерфейс jQuery для сортування, але, здається, це не так. Будь-які думки?
Я тут трохи не в глибині, і сподіваюся, що це насправді можливо.
Мені б хотілося викликати функцію, яка б сортувала всі елементи мого списку за алфавітом.
Я переглядав інтерфейс jQuery для сортування, але, здається, це не так. Будь-які думки?
Відповіді:
Для цього вам не потрібен 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");
Щось на зразок цього:
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
$(".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
$(".list li").sort(function(a, b){return ($(b).text()) < ($(a).text());}).appendTo('.list');
. Хоча одне зауваження: .text()
має бути.text().toUpperCase()
$(".list").children()
, якщо можливо, або налаштувати селектор з негайними стосунками з дитиною, наприклад$(".list > li")
Щоб ця робота працювала з усіма браузерами, включаючи Chrome, вам потрібно зробити функцію зворотного дзвінка sort () return -1,0 або 1.
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, ви можете зробити це:
$(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) з функції порівняння абсолютно неправильно .
@ SolutionYogi відповідає як шарм, але здається, що використання $ .each є менш простим та ефективним, ніж безпосередньо додавання 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);
вдосконалення на основі джеетендра Чаухан відповіді «s
$('ul.menu').each(function(){
$(this).children('li').sort((a,b)=>a.innerText.localeCompare(b.innerText)).appendTo(this);
});
чому я вважаю це вдосконаленням:
використовуючи each
для підтримки біг на більш ніж один ul
використання children('li')
замість цього ('ul li')
важливо, оскільки ми хочемо обробляти лише дітей, а не нащадків
використання функції стрілки (a,b)=>
просто виглядає краще (IE не підтримується)
використання ванілі innerText
замість $(a).text()
для покращення швидкості
використання ванілі localeCompare
покращує швидкість у випадку рівних елементів (рідкісне в реальному житті)
використання appendTo(this)
замість іншого селектора гарантує, що навіть якщо селектор наздожене більше одного ul, все одно нічого не зламається
Я хотів це зробити сам, і я не був задоволений будь-якою з наданих відповідей просто тому, що, я вважаю, вони є квадратичним часом, і мені потрібно це робити у списках сотень предметів.
Я закінчив розширення 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)));
}
}
Помістіть список у масив, використовуйте JavaScript .sort()
, який за замовчуванням є алфавітним, а потім перетворите масив назад у список.
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 https://jsfiddle.net/97oo61nw/
Тут ми висуваємо всі значення li
елементів всередині ul
з конкретними id
(які ми надали як аргумент функції) для масиву arr
та сортування за допомогою методу sort (), який сортується за алфавітом за замовчуванням. Після arr
сортування масиву ми обв'язуємо цей масив методом forEach () і просто замінюємо текстовий вміст усіх li
елементів на відсортований вміст