如果我们稍微更改您的标记以更好地处理链接,如下所示:
<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();
});
You can test it out here,当然还有其他方法(以上可以进一步精简)...我的主要观点是用Array.sort() 演示你可以很快完成这个工作。
以下是上述内容的细分:
- 获取
#XXX 并获取XXX,这就是我们要排序的类(您可以在此处使用data- attribute)
- 获取列表 - 保留参考,以免我们一直选择它
- 以孩子(
<li>s)为例,使用.get() 获取 DOM 元素的原始数组
-
.sort() 该数组由:
- 传入
a和b,这些是<li>元素
-
.find() <span> 我们愿意在里面排序
- 拿那个
<span>的.text()
- 返回该文本的比较结果(如果我们是
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();
});
You can test out that version here.