jQuery divide la lista larga de ul en listas más pequeñas

Tengo una larga lista de UL que necesito dividir en listas más pequeñas que contienen aproximadamente 20 elementos cada una.

Estaba pensando que podría usar algo como

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

Pero ese no es el caso. ¿Alguna idea de cómo usar jQuery de una manera que use CPU mínima?

Yo crearía fragmentos de documentos con sus líneas eliminadas y luego las volvería a agregar a la ubicación que desea. En este caso, los volví a agregar al cuerpo:

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

    La demostración en vivo está en: http://jsbin.com/ejigu/33

    Nada tan simple (que yo sepa, al menos) desafortunadamente. Prueba esto como una 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 = $("
      ").insertAfter(list); list = new_list; current_size = 1; } list.append(this); }); }); });

      Sin duda podría convertir esto en una función que toma el tamaño del fragmento como argumento, pero lo dejo como un ejercicio para el lector.

      Aquí hay un ejemplo de trabajo, simplemente cambie el mod 5 por el mod 20.

           
      • item1
      • item2
      • item3
      • item4
      • item5
      • item6
      • item7
      • item8
      • item9
      • item10
      • item11
      • item12
      • item13
      • item14
      • item15
      • item16
      • item17
      • item18
      • item19
      • item20

      función:

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

      uso:

       $('ul#slides').splitUp(4,'<li class=splitUp><ul>') 

      o:

       $('div#slides').splitUp(3,'<div/>') 

      este divide el menú en partes de la función de igual longitud splitMenu (menu_id, pieces) {

        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){ $('
        ').attr('class',$($menu).attr('class')).append(group).appendTo($($menu).parent()); } $($menu).remove(); } splitMenu('#menu-footermenu', 2);

      Solo otra versión como un plugin jQuery:

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

        Aquí hay otra opción: no he perfilado ninguno de los anteriores, así que ve con lo que sea más rápido, por supuesto. Supone que el ul en cuestión tiene el id de #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#list").replaceWith($("ul#list").children());

          puedes probar algo como esto:

           $("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 = $("
            "); $(list).after(new_list); new_list.append($(list).find("li:gt(20)")); if(new_list.find("li").length > 20){ split_list(new_list); } } }

            LE: Creo que se puede refinar aún más si descubrimos la cantidad de listas nuevas que se crearán, crearemos esas listas y moveremos bloques de ~ 20 li en las nuevas listas creadas para que se muevan solo una vez.

            Aquí hay una extensión del objeto jQuery prototype ($ .fn) para proporcionar un nuevo método que se puede encadenar a la función jQuery ().

            Necesitaba funcionalidad donde necesitaba agregar un elemento entre la lista que dividía. Eso se ha agregado como un parámetro opcional.

            Un ejemplo está disponible en http://jsfiddle.net/roeburg/5F2hW/

            El uso de la función es así:

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

            La función se define de la siguiente manera:

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

            Espero que esto ayude.

            Algo como esto:

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

            Demo de trabajo