Если мы немного изменим вашу разметку, чтобы лучше обрабатывать ссылки, например:
<div id="sort">
<a href="#name">Sort by name</a>
<a href="#year">Sort by year</a>
<a href="#fruit">Sort by fruit</a>
</div>
<ul id="things">
Вы можете сделать простую двухстороннюю сортировку, например:
$("#sort a").click(function(e) {
var desc = $(this).hasClass("asc"),
sort = this.hash.substr(1),
list = $("#things");
list.append(list.children().get().sort(function(a, b) {
var aProp = $(a).find("span."+sort).text(),
bProp = $(b).find("span."+sort).text();
return (aProp > bProp ? 1 : aProp < bProp ? -1 : 0) * (desc ? -1 : 1);
}));
$(this).toggleClass("desc", desc)
.toggleClass("asc", !desc)
.siblings().removeClass("asc desc");
e.preventDefault();
});
Вы можете проверить это здесь , конечно, есть и другие подходы (и выше можно уменьшить) ... моя главная цель здесь была продемонстрировать с помощью Array.sort()
вы можетесделай это довольно быстро.
Вот разбивка того, что делает вышеприведенное:
- Возьмите
#XXX
и получите XXX
, это класс, по которому мы хотим отсортировать (вы можете использовать data-
атрибут здесь) - Возьмите список - сохраните ссылку, чтобы мы не продолжали выбирать его
- Возьмите детей (
<li>
s), используйте .get()
для получения необработанного массива элементов DOM .sort()
этого массива: - Возьмите
a
и b
, переданные вэто элементы <li>
.find()
<span>
, в которых мы хотим разобраться - Возьмите
.text()
из этого <span>
- Возврат сравнения этого текста (в обратном случае, если мы
desc
, обратный сортировка)
.append()
отсортированные элементы обратно в list
- Последний бит просто меняет стиль сортировки, если он уже отсортирован по возрастанию, измените его на класс
desc
, в противном случае сделайте его asc
класс, и удалите любой класс из любых братьев и сестер.
Если у вас очень большое количество элементов, вам нужно использовать другой подход, такой как плагины, опубликованные в других ответах ... они анализируют данные только по обновлениям и кэшируют результат в объектах, поэтомупри сортировке меньше обхода DOM (который по сравнению со всем остальным стоит дороже).
В качестве примера того, как улучшить вышеупомянутое (но менее читабельное в качестве примера), можно было бы выбрать <span>
элементы изначально, сокращая селектор и .text()
время, например:
$("#sort a").click(function(e) {
var desc = $(this).hasClass("asc"),
sort = this.hash.substr(1),
list = $("#things");
$(list.children().detach().find("span."+sort).get().sort(function(a, b) {
var aProp = $.text([a]),
bProp = $.text([b]);
return (aProp > bProp ? 1 : aProp < bProp ? -1 : 0) * (desc ? -1 : 1);
})).parent().appendTo(list);
$(this).toggleClass("desc", desc)
.toggleClass("asc", !desc)
.siblings().removeClass("asc desc");
e.preventDefault();
});
Вы можете проверить эту версию здесь .