2010-05-22 71 views
14

我有兩個彼此相鄰的有序列表。使用jQuery按字母順序動態插入到列表中

當我從一個列表中取出一個節點時,我想按字母順序將其插入到另一個列表中。問題的關鍵是我想只取出一個元素,並將其放回到另一個列表中,而不刷新整個列表。

奇怪的是,當我插入到右側的列表中時,它可以正常工作,但是當我插入到左側列表中時,順序永遠不會出現正確。

我也試過將所有東西都讀入數組並在那裏排序,以防萬一children()方法沒有按照它們顯示的順序返回東西,但我仍然得到相同的結果。

這裏是我的jQuery:

function moveNode(node, to_list, order_by){ 

    rightful_index = 1; 
    $(to_list) 
     .children() 
     .each(function(){ 
      var ordering_field = (order_by == "A") ? "ingredient_display" : "local_counter"; 

      var compA = $(node).attr(ordering_field).toUpperCase(); 
      var compB = $(this).attr(ordering_field).toUpperCase(); 
      var C = ((compA > compB) ? 1 : 0); 
      if(C == 1){ 
       rightful_index++; 
      } 
     }); 

    if(rightful_index > $(to_list).children().length){ 
     $(node).fadeOut("fast", function(){ 
      $(to_list).append($(node)); 
      $(node).fadeIn("fast"); 
     }); 
    }else{ 
     $(node).fadeOut("fast", function(){ 
      $(to_list + " li:nth-child(" + rightful_index + ")").before($(node)); 
      $(node).fadeIn("fast"); 
     }); 
    } 

} 

這裏是我的html的樣子:

<ol> 
<li ingredient_display="Enriched Pasta" ingredient_id="101635" local_counter="1"> 
    <span class="rank">1</span> 
    <span class="rounded-corners"> 
      <span class="plus_sign">&nbsp;&nbsp;+&nbsp;&nbsp;</span> 
      <div class="ingredient">Enriched Pasta</div> 
      <span class="minus_sign">&nbsp;&nbsp;-&nbsp;&nbsp;</span> 
    </span> 
</li> 
</ol> 
+0

您是否嘗試過使用調試器來逐步通過您的代碼,並確保您的每一個(...)回調函數正確行爲? Firebug或IE8開發者工具對此非常有用。您可以在回調的主體中放置一個斷點。 – RMorrisey 2010-05-22 02:41:43

+1

我檢查了w3c。我找不到任何提及的'ingredient_display','ingredient_id'或'local_counter'屬性。除此之外,這是一些可怕的html。我希望這不會進入生產的某個地方:\ – Jason 2010-05-22 03:11:00

+0

我已經通過使用螢火蟲,由於某種原因,他們沒有以正確的順序回來的其中一個有序列表。也許我應該通過getElementById來代替。 @jason,這不是生產。這些是用戶定義的屬性。你會如何建議解決這個問題? – Dex 2010-05-22 04:13:19

回答

26

我已經創建了一個jsFiddle with working code來解決這個問題。我包括這裏的代碼以及以防萬一的jsfiddle進肚子了在遙遠的未來:

<ol class="ingredientList"> 
    <li class="ingredient">Apples</li> 
    <li class="ingredient">Carrots</li> 
    <li class="ingredient">Clams</li> 
    <li class="ingredient">Oysters</li> 
    <li class="ingredient">Wheat</li> 
</ol> 
<ol class="ingredientList"> 
    <li class="ingredient">Barley</li> 
    <li class="ingredient">Eggs</li> 
    <li class="ingredient">Millet</li> 
    <li class="ingredient">Oranges</li> 
    <li class="ingredient">Olives</li> 
</ol>​ 

和jQuery的:

$(".ingredient").click(function(){ 
    var element = $(this); 
    var added = false; 
    var targetList = $(this).parent().siblings(".ingredientList")[0]; 
    $(this).fadeOut("fast", function() { 
     $(".ingredient", targetList).each(function(){ 
      if ($(this).text() > $(element).text()) { 
       $(element).insertBefore($(this)).fadeIn("fast"); 
       added = true; 
       return false; 
      } 
     }); 
     if(!added) $(element).appendTo($(targetList)).fadeIn("fast"); 
    }); 
});​ 

我剝你的HTML下來簡潔起見,所以你會想修改我的代碼來匹配你的。另外,如果你打算使用用戶定義的屬性(它不是有效的HTML,並且沒有被任何瀏覽器正式支持......雖然它也不會損害任何東西....可能),但我建議在它們前面添加「data- 「以符合HTML5 Custom Data Attribute規範。所以「ingredient_id」會變成「data-ingredient_id」。儘管目前的瀏覽器尚未支持HTML5,但HTML5尚未最終確定,但它比定義自己的屬性更安全,更強大。一旦HTML5完成,您的屬性將得到完全支持。

編輯 - 正如John在評論中指出的那樣,如果您需要支持UTF-8字符,這將不起作用。在這種情況下,您需要使用String.prototype.localeCompare()(確保您按照文檔檢查瀏覽器是否支持它)。所以代碼看起來像這樣:

$(".ingredient").click(function(){ 
    var element = $(this); 
    var added = false; 
    var targetList = $(this).parent().siblings(".ingredientList")[0]; 
    $(this).fadeOut("fast", function() { 
     $(".ingredient", targetList).each(function(){ 
      if ($(this).text().localeCompare($(element).text()) > 0) { 
       $(element).insertBefore($(this)).fadeIn("fast"); 
       added = true; 
       return false; 
      } 
     }); 
     if(!added) $(element).appendTo($(targetList)).fadeIn("fast"); 
    }); 
}); 

Here is an updated Fiddle implementing localeCompare

+0

我試過了你的方法,當你使用.text()時它確實有效。但是,我使用.text()時也可以工作。當我使用.attr()時,它們都會中斷。我已經停止使用用戶定義的屬性,只是試着玩'id'屬性,我仍然得到相同的奇怪行爲。調試告訴我,.children()實際上是按正確順序迭代的。這太令人沮喪了。 – Dex 2010-05-25 14:00:12

+0

我確實需要按字母順序排序。我需要也能夠通過我的原始HTML中的'local-counter'字段進行排序。 – Dex 2010-05-25 14:02:55

+0

我剛剛更新了jsFiddle以.attr()命令,它似乎工作。 http://jsfiddle.net/VQu3S/9/ – 2010-05-25 14:38:13

-3

我會得到的.text()的每個元素冷杉,然後把它的陣列上對數組進行排序,然後移動SORTED的索引與UNSORTED匹配的每個元素。

我懶得爲它編寫代碼,現在就測試它:)但只是想到了接近它的方式。