2009-10-29 2 views
11

Ho una lunga lista UL che devo suddividere in elenchi più piccoli contenenti circa 20 articoli ciascuno.jQuery suddiviso in elenchi più piccoli in elenchi più piccoli

stavo pensando che potrei usare qualcosa come

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

ma non è questo il caso. Qualche idea su come usare jQuery in un modo che usi una CPU minima?

+1

V'è una libreria che fa questo - https://github.com/yairEO/listBreaker – vsync

risposta

19

Vorrei creare frammenti di documento con gli li rimossi e quindi riapplicarli nella posizione desiderata. In questo caso, li ho reappended al corpo:

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

Demo Live e ': http://jsbin.com/ejigu/33

+2

Solo per correre Ho provato a fare questo con regex invece: http://jsbin.com/acupof/2/edit#javascript,live ... Non posso dire che sia più elegante. :) –

+1

Per velocità pura, la soluzione regex potrebbe essere migliore. Se hai cambiato la mia risposta per usare 'detach' invece di' remove', manterrebbe qualsiasi evento che è stato collegato agli elementi o ai sottoelementi. Ciò sarebbe utile in alcune situazioni. Anche se con liste lunghe, probabilmente dovresti delegare comunque. <3z –

+0

Chi è un brutto culo? Paul Irish, ecco chi :) ........ ben fatto! – Oneezy

7

Sfortunatamente niente di così semplice (di cui sono a conoscenza almeno). Prova questo come alternativa:

$(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); 
    }); 
    }); 
}); 

Si potrebbe senza dubbio trasformare questo in una funzione che prende la dimensione del blocco come argomento, ma lascio che come esercizio per il lettore.

3

Ecco un esempio di lavoro, basta cambiare il mod 5 al 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

Qui è un'altra opzione - non ho profilato nessuno dei precedenti, quindi vai con quello che è più veloce, naturalmente. Suppone che l'ul in questione abbia l'id di #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

si può provare qualcosa di simile:

$("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: Penso che può essere ulteriormente affinata trovando in anticipo quanti nuova lista sarà createt, creare tali elenchi e spostare blocchi di ~ 20 li sono nei nuovi elenchi creati in modo che vengano spostati una sola volta.

2

funzione:

$.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); 
} 

Utilizzo:

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

o:

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

Se lo fai ricorsivo è ancora più corto –

1

questo divide il menu in pezzi di lunghezza approssimativamente uguale funzione Splitmenu (menu_id, pezzi) {

 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

solo un'altra versione come un 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

Ecco un'estensione del prototipo jQuery ($ .fn) oggetto di fornire un nuovo metodo che può essere incatenato alla funzione jQuery().

Avevo bisogno di funzionalità in cui avevo bisogno di aggiungere un elemento tra la lista che ho diviso. Questo è stato aggiunto come parametro opzionale.

Un esempio è disponibile presso http://jsfiddle.net/roeburg/5F2hW/

L'utilizzo della funzione è in questo modo:

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

La funzione è definita come segue:

// 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); 

Spero che questo aiuti.

0

Qualcosa di simile a questo:

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