作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在开发一个带有导航叠加层(节点和子节点)的响应式网站。导航应拆分为桌面 View 的 4 列或平板 View 的 2 列。这是一个嵌套列表导航,因此使用 <ul />
构建了一个列周围。我的想法是,只需将导航写在 1 列中,然后使用 jquery 将其动态排列为 4 或 2 列。
html:
<!-- overlay -->
<nav class="overlay">
<!-- ul for column -->
<ul>
<!-- nodes & subnodes -->
<li><a href="#">node</a>
<ul>
<li><a href="#">subnode</a></li>
<li><a href="#">subnode</a></li>
<li><a href="#">subnode</a></li>
<li><a href="#">subnode</a></li>
</ul>
</li>
<li><a href="#">node</a>
<ul>
<li><a href="#">subnode</a></li>
<li><a href="#">subnode</a></li>
<li><a href="#">subnode</a></li>
<li><a href="#">subnode</a></li>
<li><a href="#">subnode</a></li>
<li><a href="#">subnode</a></li>
<li><a href="#">subnode</a></li>
<li><a href="#">subnode</a></li>
</ul>
</li>
<li><a href="#">node</a> ...
</ul>
</nav>
我写了这个函数:
$.fn.arrangeObjects = function(wrapWith, maxCols) {
this.each(function() {
if ($(this).parent(wrapWith).length) $(this).unwrap();
});
this.parent().each(function() {
var $el = $(this).children();
amount = $el.length,
wrapAmount = amount / maxCols;
for (var i = 0; i < amount; i += wrapAmount) {
$el.slice(i, i + wrapAmount).wrapAll('<'+ wrapWith +'/>');
}
});
};
为台式机触发:
$(".overlay > ul > li").arrangeObjects('ul', 4);
为平板电脑触发:
$(".overlay > ul > li").arrangeObjects('ul', 2);
此解决方案将节点分成等份的列。不幸的是,这样看起来不太好:
http://bern09.ch/notgood.png
我想要实现的是排列几乎相同的列高,如下所示:
http://bern09.ch/good.png
我必须以某种方式尊重子节点的数量,但我真的不知道如何实现。也许任何人都有很好的提示,我们将不胜感激。
最佳答案
好的。我懂了。这有点棘手。昨天我开始计算每一列的高度,但我相信这种方法更灵活:
this.parent().each(function () {
var $subnodes = $(this).children();
// true will cause counter increment
// false will cause counter decrement
var inc = true;
var cols = [];
for (var i = 0; i < maxCols; i++) {
cols.push($('<ul></ul>'));
cols[i].appendTo($(this));
}
function sortByHeight(a, b) {
return $(a).height() > $(b).height() ? 0 : 1;
}
$subnodes = $subnodes.sort(sortByHeight);
var i = 0;
$subnodes.each(function () {
// logic for left and right boundry
if (i < 0 || i === maxCols) {
inc = !inc;
// this will cause node to be added once again to the same column
inc ? i++ : i--;
}
cols[i].append($(this));
inc ? i++ : i--;
});
});
这是一个概念。首先,我按高度(从最高到最低)对所有节点进行排序,然后将它们附加到从左到右再返回的列(由 maxCols 指定)。它不像你的那么漂亮,不幸的是打破了 wrapAll 的使用(我非常喜欢它)。我已经在进行一个小的优化,它将使用 threshold
范围。当最短列和最长列之间的高度差大于阈值时,最长列的最后一个元素将移动到最短列。它应该看起来更自然。让我知道这是否是您要找的。
关于jquery - 如何将嵌套导航拆分为高度几乎相等的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14058474/
我是一名优秀的程序员,十分优秀!