2009-10-29 9 views
11

Mam długą listę UL, którą muszę podzielić na mniejsze listy zawierające około 20 pozycji.jQuery podzieliłem długą listę ul na mniejsze listy

Myślałam mogłem użyć czegoś jak

$(function() { 
    $("ul li:nth-child(20n)").after("</ul><ul>"); 
}); 

jednak, że nie jest to przypadek. Każdy pomysł, jak korzystać z jQuery w sposób, który wykorzystuje minimalną CPU?

+1

Jest biblioteka, która to robi - https://github.com/yairEO/listBreaker – vsync

Odpowiedz

19

Chciałbym utworzyć fragmenty dokumentów z usuniętymi li s, a następnie ponownie je do miejsca, które chcesz je. W tym przypadku, reappended je do ciała:

$(function(){ 
    var $bigList = $('#bigList'), group; 
    while((group = $bigList.find('li:lt(20)').remove()).length){ 
    $('<ul/>').append(group).appendTo('body'); 
    } 
}); 

żywo demo pod adresem: http://jsbin.com/ejigu/33

+2

Tylko na metę Próbowałem robić to z regex zamiast tego: http://jsbin.com/acupof/2/edit#javascript,live ... Nie mogę powiedzieć, że jest bardziej elegancki. :) –

+1

Dla samej prędkości rozwiązanie regex może być lepsze. Jeśli zmienisz moją odpowiedź na "odejmuj" zamiast "usuń", to zachowa wszelkie zdarzenia, które zostały dołączone do elementów lub podelementów. Byłoby to pomocne w niektórych sytuacjach. Chociaż z długimi listami prawdopodobnie i tak powinno się delegować. <3z –

+0

Kto to jest zły tyłek? Paul Irish, to kto :) ........ ładnie zrobione! – Oneezy

7

Niestety, nic nie jest tak proste (przynajmniej o tym wiem). Spróbuj to jako alternatywę:

$(function() { 
    $("ul").each(function() { 
    var list = $(this); 
    var size = 3; 
    var current_size = 0; 
    list.children().each(function() { 
    console.log(current_size + ": " + $(this).text()); 
     if (++current_size > size) { 
     var new_list = $("<ul></ul>").insertAfter(list); 
     list = new_list; 
     current_size = 1; 
     } 
     list.append(this); 
    }); 
    }); 
}); 

Można bez wątpienia przekształcić funkcję, która pobiera wielkość porcji jako argument, ale zostawiam to jako ćwiczenie dla czytelnika.

3

Oto przykład działa, wystarczy zmienić mod 5 do mod 20.

<html> 
<script type="text/javascript" src="jquery-1.3.2.js"></script> 

<script type="text/javascript"> 

function onLoad(){ 
    var itemindex = 0; 
    var Jlistobj = null; 
    $('#list li').each(function() 
    { 
     if (itemindex % 5 == 0) 
     { 
     Jlistobj = $("<ul></ul>"); 
     } 
     Jlistobj.append($(this)); 
     $('#out_div').append(Jlistobj); 
     itemindex++; 
    }); 
} 

</script> 
<body onLoad="onLoad()"> 

<ul id="list"> 
<li>item1</li> 
<li>item2</li> 
<li>item3</li> 
<li>item4</li> 
<li>item5</li> 
<li>item6</li> 
<li>item7</li> 
<li>item8</li> 
<li>item9</li> 
<li>item10</li> 
<li>item11</li> 
<li>item12</li> 
<li>item13</li> 
<li>item14</li> 
<li>item15</li> 
<li>item16</li> 
<li>item17</li> 
<li>item18</li> 
<li>item19</li> 
<li>item20</li> 
</ul> 

<div id="out_div"></div> 

</body> 

</html> 
0

Tutaj to kolejna opcja - nie profilowałem żadnego z powyższych, więc idź z czymkolwiek, co jest najszybsze oczywiście. Zakłada on, że dany ul ma identyfikator #list.

 var listItemsPerList = 10; 
    var listItems = $("ul > li").length; 

    for (var i = 0; i < Math.round(listItems/listItemsPerList); i++) { 
     var startingItem = i * listItemsPerList; 
     var endingItem = (i + 1) * listItemsPerList; 
     if (endingItem > listItems) { endingItem = listItems }; 
     $("ul > li").slice(startingItem, endingItem).wrapAll("<ul></ul>"); 
    } 

    $("ul#list").replaceWith($("ul#list").children()); 
0

można spróbować coś takiego:

$("ul").each(function(k,v)){ 
    split_list(v); 
} 

function split_list(list){ 
    var li_num = $(list).find("li").length; 
    if(li_num > 20){ 
     var new_list = $("<ul></ul>"); 
     $(list).after(new_list); 
     new_list.append($(list).find("li:gt(20)")); 
     if(new_list.find("li").length > 20){ 
      split_list(new_list); 
     } 
    } 
} 

LE: Myślę, że to może być dalej udoskonalane przez znalezienie się frontu ile nowa lista będzie createt, tworzenie tych list i przesunąć bloki ~ 20 li do nowych utworzonych list, więc zostaną przeniesione tylko raz.

2

funkcji:

$.fn.splitUp=function(splitBy,wrapper) { 
    $all= $(this).find('>*'); 
    var fragment=Math.ceil($all.length/splitBy); 
    for(i=0; i< fragment; i++) 
     $all.slice(splitBy*i,splitBy*(i+1)).wrapAll(wrapper); 
    return $(this); 
} 

zastosowanie:

$('ul#slides').splitUp(4,'&lt;li class=splitUp&gt;&lt;ul&gt;') 

czyli

$('div#slides').splitUp(3,'&lt;div/&gt;') 
+0

Jeśli zrobisz rekurencję, jest jeszcze krótszy –

1

ten dzieli menu na kawałki w przybliżeniu równej długości funkcyjne splitMenu (menu_id, kawałki) {

 var $menu = $(menu_id), group; 
     var splitItem = 0, totItemLen = 0, cumlen = 0; 

     $($menu).find('li').each(function(){ totItemLen = totItemLen + $(this).width(); }); 

     $($menu).find('li').each(function(i){ 
      cumlen = cumlen + $(this).width(); 
      if (totItemLen/pieces < cumlen && splitItem == 0) splitItem = i; 
     }); 

     while((group = $($menu).find('li:lt(' + splitItem + ')').remove()).length){ 
       $('<ul/>').attr('class',$($menu).attr('class')).append(group).appendTo($($menu).parent()); 
      } 

     $($menu).remove(); 
    } 
    splitMenu('#menu-footermenu', 2); 
1

Kolejna wersja jako plugin jQuery:

jQuery.fn.splitList = function(num) { 
    var sublist; 
    while((sublist = this.find('li:gt('+(num-1)+')').remove()).length){ 
    this.after($('<ul/>').append(sublist)); 
    } 
}; 
0

Oto rozszerzenie prototyp jQuery ($ .fn) celem jest dostarczenie nowej metody, które mogą być przykuty do funkcji jQuery().

Potrzebowałem funkcjonalności, w której potrzebowałem dodać element między listą, którą podzielę. Zostało to dodane jako parametr opcjonalny.

Przykładem jest dostępny http://jsfiddle.net/roeburg/5F2hW/

Zastosowanie funkcji jest tak:

$("ul").customSplitList(5); 

funkcja jest określona w następujący sposób:

// Function definition 
(function ($) { 
    // Function is defined here ... 
    $.fn.customSplitList = function (indexToSplit, elementToAddInBetween) { 
     // Holds a reference to the element(list) 
     var that = this; 
     var subList, newList, listLength; 

     // Only continue if the element is a derivitive of a list 
     if ($(that) && ($(that).is("ul") || $(that).is("ol"))) { 

      // Additionally check if the length & the split index is valid 
      listLength = $(that).children().length; 

      if ($.isNumeric(indexToSplit) && indexToSplit > 0 && indexToSplit < listLength) { 
       // Based on list type, create a new empty list 
       newList = $($(that).clone(true)).empty(); 

       while ((subList = this.find('li:gt(' + (indexToSplit - 1) + ')').remove()).length) { 
        newList.append(subList); 
       } 

       if (elementToAddInBetween && $(elementToAddInBetween)) { 
        that.after(newList); 
        newList.before(elementToAddInBetween); 
       } else { 
        that.after(newList); 
       } 
      } 
     } 
    }; 

})(jQuery); 

nadzieja pomaga.

0

coś takiego:

var lis = $("ul > li"); 
for(var i = 0; i < lis.length; i+=20) { 
    lis.slice(i, i+20).wrapAll("<ul></li>"); 
} 
$("ul > ul").unwrap(); 

Working Demo

Powiązane problemy