jquery - 如何将嵌套导航拆分为高度几乎相等的列

标签 jquery html split responsive-design

我正在开发一个带有导航叠加层(节点和子节点)的响应式网站。导航应拆分为桌面 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/

相关文章:

JavaScript 不检测动漫 js

java - 将 HTML 内容设置为 JTextPane 会扰乱 System.out 重定向

html - Bootstrap 导航栏无法正常工作

java - Arraylist 分为 -

jquery - Rails 应用页面源码

php - 如何在图像上叠加忙碌图标?

c# - 如何同时刷新局部 View 和主视图?

javascript - 如何将自动播放的音量设置为特定级别?

javascript - 根据Javascript中的indexOf位置拆分数组并组合成单独的数组

c# - 按大写字母拆分字符串(不包括带连字符的单词)