我有一个案例,我提供了一个UL和一个未知数量的LI。我希望使用JS将LI分成2个UL(我正在使用jQuery)。我能够通过LI的数量均匀地分割UL,但是我想根据每个LI的高度将它分开,以便两个UL都接近相同的高度。
任何对此的帮助都会受到赞赏,我不觉得我已经开始采用我开始采用的方法了。
感谢。
编辑:我目前拥有的JS代码。 HTML只是一个直接的UL / LI,每个LI可以有不同的高度。var $sections = $('div.subsection');
$sections.each(function(){
var $section = $(this);
var $list = $section.children('ul');
var $items = $list.children('li');
var itemCount = $items.size();
var leftover = itemCount % 2;
var itemsPerColumn = Math.floor(itemCount / 2);
var $newList = $('<ul />');
$items.each(function(){
var $this = $(this);
var index = $items.index($this);
if (index >= (itemsPerColumn + leftover)) {
$this.remove().appendTo($newList);
}
});
$list.after($newList);
_equalizeListHeights();
function _equalizeListHeights(){
var listHeight = $list.height();
var newListHeight = $newList.height();
if (listHeight > newListHeight){
var $lastItem = $list.children('li:last');
var lastItemHeight = $lastItem.height();
if (listHeight - lastItemHeight > newListHeight + lastItemHeight){
$lastItem.remove().prependTo($newList);
_equalizeListHeights();
}
}
}
});
答案 0 :(得分:2)
你可以通过CSS来实现:
.double_column_list li {float: left; width: 50%;}
<ul class="double_column_list">
<li>Awesome Stuff Awesome Stuff Awesome Stuff Awesome Stuff Awesome Stuff</li>
<li>Awesome Stuff</li>
<li>Awesome Stuff</li>
<li>Awesome Stuff</li>
</ul>
要获得3列,请设置width: 33.333%
,列width: 25%
,依此类推。
当然,如果你继续将li
的高度增加到li
的其余部分无法匹配的点,那么这看起来会很糟糕。但是,这个问题也无法通过JS解决。
<强>更新强> 正如评论者所指出的,如果列表项没有按高度排序(即中间任何一个列表项的高度可能比前面的列表项更高/更小),则需要排序:http://jsfiddle.net/rQJQb/2/
答案 1 :(得分:1)
我想我至少可以在这里看到这种方法:
total
)的总高度,并存储所有单独的高度total / 2
)heights
的一组total / 2
与window.resize
相加,但不得超过它。第3步是棘手的一点。它与Subset Sum Problem。
有关 Here's a brute-force algorithm解决了您的问题。它不会在//Sum a jQuery wrapped array
$.fn.sum = function() {
var total = 0;
this.each(function() { total += this; });
return total;
};
//Mask elements with a bitmask
$.fn.mask = function(mask) {
return this.filter(function(i) {
return (mask >> i) & 1;
})
}
//Get the sizes, and sneakily return a jQuery object
var sizes = $('.first li').map(function() { return $(this).outerHeight() });
var total = sizes.sum();
var maxTotal = total / 2;
var best = {
total: 0,
mask: 0
}
for (var subsetMask = 1; subsetMask < (1 << sizes.length); subsetMask++) {
//Sum all the heights in this subset
var subsetTotal = sizes.mask(subsetMask).sum();
//New optimal solution?
if (subsetTotal > best.total && subsetTotal <= maxTotal) {
best = {
total: subsetTotal,
mask: subsetMask
};
}
}
$('.first li').mask(best.mask).appendTo('.second');
上运行,因为那会很愚蠢。如果要查看更改,请调整结果窗口的大小,然后按下运行。
{{1}}
答案 2 :(得分:1)
您要解决的CS问题
您应该查看Backpack Problem。要“插入背包”的物品将是LI。每个LI的重量和值都等于其高度。背包容量应该是所有LI高度的一半。运行算法来解决背包问题,你的LI将被分为两组,如你所描述的那样高。
直观的解释
背包算法找到项目的子集,使得该值尽可能大,但重量不超过背包容量。但是我们每个LI的重量和价值都是它的高度,背包容量是所有LI组合总高度的一半。
基本上它给我们的是一组所有LI,使得高度尽可能高,不超过总高度的1/2。在你最终应该有两个相等高度的LI组的情况下,这将是其中一组。如果您最终应该使用两组具有不同高度的LI,则背包问题解决方案将返回具有较小高度的集合(并且剩余的,未选择的LI将是第二组)。
<强>解决方案强>
尝试使用此处使用的代码:http://rosettacode.org/wiki/Knapsack_problem/Bounded#JavaScript
或者如果你想自己动手(不推荐 - 为什么要这么麻烦?):http://en.wikipedia.org/wiki/Knapsack_problem#Unbounded_knapsack_problem
答案 3 :(得分:0)
$("ul.first li").each(function() {
if ($("ul.first").outerHeight() > $("ul.second").outerHeight()) {
$(this).appendTo($("ul.second"));
}
});
使用此jQuery代码。