jQuery разделил длинный список ul на более мелкие списки

StackOverflow https://stackoverflow.com/questions/1644668

  •  10-07-2019
  •  | 
  •  

Вопрос

У меня есть длинный список UL, который мне нужно разбить на более мелкие списки, содержащие примерно по 20 элементов в каждом.

Я подумал, что мог бы использовать что-то вроде

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

но это не тот случай.Есть идеи, как использовать jQuery таким образом, чтобы использовать минимум процессора?

Это было полезно?

Решение

Я хотел бы создать фрагменты документа с вашими удаленными li и затем повторно добавить их в нужное место. В этом случае я снова добавил их в тело:

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

Живая демоверсия находится по адресу: http://jsbin.com/ejigu/33

Другие советы

К сожалению, не все так просто (о чем я знаю). Попробуйте это как альтернативу:

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

Без сомнения, вы можете превратить это в функцию, которая принимает размер куска в качестве аргумента, но я оставляю это как упражнение для читателя.

Вот рабочий пример, просто измените мод 5 на мод 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>

функция:

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

использование:

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

или:

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

этот разделит меню на части примерно одинаковой длины функция splitMenu (menu_id, штук) {

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

Просто еще одна версия в качестве плагина jQuery:

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

Вот еще один вариант - я не описал ничего из вышеперечисленного, так что, конечно, делайте все, что быстрее. Предполагается, что рассматриваемый ul имеет идентификатор #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());

вы можете попробовать что-то вроде этого:

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

Л.Е .: Я думаю, что это можно уточнить, предварительно выяснив, сколько новых списков будет создано, создайте эти списки и переместите блоки ~ 20 строк в новые созданные списки, чтобы они были перемещены только один раз.

Вот расширение объекта-прототипа jQuery ($ .fn) для предоставления нового метода, который можно связать с функцией jQuery ().

Мне нужно было функционировать там, где мне нужно было добавить элемент в список, который я разделил. Это было добавлено в качестве необязательного параметра.

Пример доступен по адресу http://jsfiddle.net/roeburg/5F2hW/ . р>

Использование функции примерно так:

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

Функция определяется следующим образом:

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

Надеюсь, это поможет.

Примерно так:

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

Рабочая демонстрация

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top