2010-11-26 59 views
3

我有一個問題,試圖排序列表中的跨度。排序列表中的跨度,jQuery

例子:

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

所以我希望能夠通過這三個 「類別」 進行排序。任何人都有一個建議?

回答

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"> 

你可以做一個簡單的切換2路的排序是這樣的:

$("#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()數組方式:
    • 採取ab在過去,這些都是<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

+0

這真的很有用;我從中學習並創建了一個使用aria標籤的版本,而不是`a`和`hash`。我還使用Bootstrap sprites來顯示訂購狀態。 http://jsfiddle.net/jhfrench/2ZHQA/無論如何,我明天會回來看看這個答案! – 2013-01-31 21:07:09