【问题标题】:Sort a list with spans within, jQuery对带有跨度的列表进行排序,jQuery
【发布时间】:2011-05-16 05:06:56
【问题描述】:

我在尝试对包含跨度的列表进行排序时遇到问题。

例子:

<a href="">Sort by name</a>
<a href="">Sort by year</a>
<a href="">Sort by fruit</a>
<ul>
 <li>
  <span class="name">Carl</span>
  <span class="year">1954</span>
  <span class="fruit">Apple</span>
 </li>
 <li>
  <span class="name">Ann</span>
  <span class="year">1932</span>
  <span class="fruit">Banana</span>
 </li>
 <li>
  <span class="name">Joe</span>
  <span class="year">1961</span>
  <span class="fruit">Pineapple</span>
 </li>
 </ul>

所以我希望能够按这三个“类别”进行排序。有人有建议吗?

【问题讨论】:

    标签: javascript jquery list sorting


    【解决方案1】:

    如果我们稍微更改您的标记以更好地处理链接,如下所示:

    <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
    • 获取列表 - 保留参考,以免我们一直选择它
    • 以孩子(&lt;li&gt;s)为例,使用.get() 获取 DOM 元素的原始数组
    • .sort() 该数组由:
      • 传入ab,这些是&lt;li&gt;元素
      • .find() &lt;span&gt; 我们愿意在里面排序
      • 拿那个&lt;span&gt;.text()
      • 返回该文本的比较结果(如果我们是 desc,则反转,反转排序)
    • .append() 将排序后的元素返回到list
    • 最后一点只是更改排序样式,如果它已经按升序排序,则将其更改为 desc 类,否则将其设置为 asc 类,并从任何同级中删除任一类。

    如果您有大量元素,您将需要采用不同的方法,例如其他答案中发布的插件...它们仅解析更新数据并将结果缓存在对象中,因此 DOM 较少排序时遍历(与其他所有内容相比,代价高昂)。


    作为如何改进上述内容的示例(但作为示例的可读性较差)是最初选择 &lt;span&gt; 元素,减少选择器和 .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.

    【讨论】:

    • 这真的很有用;我从中学习并创建了一个使用 aria-labelledby 的版本,而不是 ahash。我还使用 Bootstrap sprites 来显示排序状态。 jsfiddle.net/jhfrench/2ZHQA 无论如何,我明天会回来为这个答案投票!
    【解决方案2】:

    我建议在表格中重新排列您的数据(因为这就是它所代表的内容),然后使用 JQuery table sorter plugin 之类的东西

    【讨论】:

      【解决方案3】:

      这也可能有帮助:jQuery Quicksand plugin

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-13
        • 1970-01-01
        • 2013-03-29
        • 2021-11-27
        • 1970-01-01
        • 2012-05-07
        • 2013-07-21
        • 2018-10-02
        相关资源
        最近更新 更多