Since I had the same problem and couldn't find anything "clean" I thought I'd posted my solution. In this example I use a reversed while
loop so I can use splice
instead of slice
. The advantage now is splice() only needs an index and a range where slice() needs an index and the total. The latter tends to become difficult while looping.
Disadvantage is I need to reverse the stack while appending.
Example:
cols = 4;
liCount = 35
for loop with slice = [0, 9]; [9, 18]; [18, 27]; [27, 35]
reversed while with splice = [27, 8]; [18, 9]; [9, 9]; [0, 9]
Code:
// @param (list): a jquery ul object
// @param (cols): amount of requested columns
function multiColumn (list, cols) {
var children = list.children(),
target = list.parent(),
liCount = children.length,
newUl = $("<ul />").addClass(list.prop("class")),
newItems,
avg = Math.floor(liCount / cols),
rest = liCount % cols,
take,
stack = [];
while (cols--) {
take = rest > cols ? (avg + 1) : avg;
liCount -= take;
newItems = children.splice(liCount, take);
stack.push(newUl.clone().append(newItems));
}
target.append(stack.reverse());
list.remove();
}