2009-10-29 67 views
11

我有一个很长的UL列表,我需要在包含大约20个项目的小列表中分解。jQuery在较小的列表中分割长的ul列表

我想我可以使用类似

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

但事实并非如此。任何想法如何以最小的CPU使用jQuery?

+1

有这确实是一个图书馆 - https://github.com/yairEO/listBreaker – vsync 2016-10-21 14:22:06

回答

19

我会用删除的li创建文档片段,然后将它们重新安装到您想要的位置。在这种情况下,我reappended他们的身体:

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

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

+2

只是为了来看,我试着用正则表达式这样做相反:http://jsbin.com/acupof/2/edit#javascript,live ...我不能说它更优雅。 :) – 2011-10-12 00:26:34

+1

对于纯粹的速度,正则表达式解决方案可能会更好。如果您将我的答案切换为使用'detach'而不是'remove',它将保留已附加到元素或子元素的所有事件。这在某些情况下会有帮助。尽管列表很长,但你可能应该委托代理。 <3z – 2011-10-12 06:01:33

+0

谁是坏人?保罗爱尔兰人,这是谁:) ........很好地完成! – Oneezy 2014-03-28 22:17:26

7

没有那么简单(至少我知道)。试试这个作为一种替代方案:

$(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

这里有一个工作的例子,只是国防部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> 
0

这里是另一种选择 - 我没有分析上述任何内容,所以请随时以最快速度进行。它假定有问题的ul有#list的id。

 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

你可以尝试这样的事:

$("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:我觉得可以通过寻找前场的许多新的名单怎么会createt进一步细化,创建这些列表和移动的块〜 20立方米进入新创建的列表,所以他们只会被移动一次。

2

功能:

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

如果你使它递归,它甚至更短 – 2012-11-21 14:12:39

1

这一拆分菜单中的近似相等的长度 功能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); 
1

只是另一个版本的jQuery插件:

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

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

希望这有助于。

0

事情是这样的:

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