【问题标题】:jQuery split long ul list in smaller listsjQuery 将长 ul 列表拆分为较小的列表
【发布时间】:2010-12-11 07:23:35
【问题描述】:

我有一个很长的 UL 列表,我需要将其分解为较小的列表,每个列表包含大约 20 项。

我在想我可以使用类似的东西

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

但事实并非如此。知道如何以使用最少 CPU 的方式使用 jQuery 吗?

【问题讨论】:

标签: jquery html split html-lists


【解决方案1】:

我会使用您删除的lis 创建文档片段,然后将它们重新附加到您想要的位置。在这种情况下,我将它们重新附加到正文中:

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

现场演示在:http://jsbin.com/ejigu/33

【讨论】:

  • 只是为了运行,我尝试使用正则表达式来代替:jsbin.com/acupof/2/edit#javascript,live ...我不能说它更优雅。 :)
  • 对于纯粹的速度,正则表达式解决方案可能会更好。如果您将我的答案切换为使用detach 而不是remove,它将保留已附加到元素或子元素的任何事件。这在某些情况下会有所帮助。尽管列表很长,但无论如何您可能都应该委派。
  • 在 while 循环中使用之前的组定义是什么?
【解决方案2】:

不幸的是,没有那么简单(至少我知道)。试试这个作为替代方案:

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

毫无疑问,您可以将其转换为以块大小为参数的函数,但我将其留给读者作为练习。

【讨论】:

    【解决方案3】:

    这是一个工作示例,只需将 mod 5 更改为 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>
    

    【讨论】:

      【解决方案4】:

      功能:

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

      【讨论】:

      • 如果你让它递归它甚至更短
      【解决方案5】:

      这个将菜单分成长度大致相等的部分 函数 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){
                      $('<ul/>').attr('class',$($menu).attr('class')).append(group).appendTo($($menu).parent());
                }
      
              $($menu).remove();  
          }  
          splitMenu('#menu-footermenu', 2);
      

      【讨论】:

        【解决方案6】:

        作为 jQuery 插件的另一个版本:

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

        【讨论】:

          【解决方案7】:

          这是另一种选择 - 我没有对上述任何内容进行分析,所以当然选择最快的。它假设有问题的 ul 的 id 为 #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());
          

          【讨论】:

            【解决方案8】:

            你可以试试这样的:

            $("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:我认为可以通过预先确定将创建多少个新列表来进一步完善它,创建这些列表并将大约 20 li 的块移动到新创建的列表中,这样它们只会被移动一次。

            【讨论】:

              【解决方案9】:

              这里是 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);
              

              希望这会有所帮助。

              【讨论】:

                【解决方案10】:

                类似这样的:

                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

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2012-07-12
                  • 2012-11-04
                  • 2010-10-19
                  • 2020-05-05
                  • 1970-01-01
                  • 2021-02-02
                  • 2021-05-13
                  • 2021-10-10
                  相关资源
                  最近更新 更多