The most efficient way to split a list into equal sized subnets using jquery

Using jQuery, what is the most efficient way to split a list

<ul class="columnar"><li></li>... <li></li></ul> 

in several subscriptions

 <ul class="column1"><li></li>... <li></li></ul> <ul class="column2"><li></li>... <li></li></ul> 

where each subscriptor (except, possibly, the last) has n elements.

I want the DOM queries and manipulations to be minimal and move the original DOM elements to new lists, rather than clone them.

+4
source share
4 answers

This is what I came up with so far:

 var $ul = $(this), items = $ul.children("li"), itemCount = items.length, colHeight = Math.ceil(itemCount/3); // create temp DOM node to place the new lists in var temp = $("<div></div>"), newUL, i = 1; while($ul.children("li").length > colHeight) { newUL = $("<ul class=\"columns\"></ul>"); newUL.append(items.filter(":gt(" + ((i * colHeight)-1) + ")").filter(":lt(" + colHeight + ")")); i++; temp.append(newUL.addClass("column" + i)); } temp.children().insertAfter($ul.attr("class","columns column1")); 
0
source

This seems to work well, not sure how effective it is:

 <ul id="column"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul> <div id="columns"></div> <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.2.min.js"></script> <script> $(document).ready( function() { var total = $("#column li").size(); console.log(total); var count = 2; var column = 0; for (var i = 0; i < total; i += count) { column++; $("#columns").append('<ul id="column' + column + '"></ul>'); $("#column" + column).html($("#column li").splice(0, count)); } $("#column").remove(); }); </script> 
0
source

Another possibility is to look at an existing plugin - several columns . The author of the plugin shows the code - you can take a look at the technique used there (CSS combos and splitting into smaller lists).

0
source

Here's my :) endyourif answer above is shorter, but it can be a little more efficient, as it first collects all the fragments and then throws them at dom with a single replacement.

 var desiredNoOfCols = 3; var $parent = $("<div/>") for(var i=1;i<=desiredNoOfCols ; i++){ $parent.append("<ul class='column" + i + "'> </ul>") } $("#column") .children() .each(function(index, elem){ $parent .children(".column" + ((index+1) % desiredNoOfCols + 1)) .append($(elem).detach()) }) .end() .replaceWith($parent.children()) 
0
source

All Articles