如何将嵌套导航拆分为高度几乎相等的列 [英] How to split a nested navigation into columns with almost equal heights

查看:68
本文介绍了如何将嵌套导航拆分为高度几乎相等的列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在一个带有导航叠加层(节点和子节点)的响应式网站上工作.对于桌面视图,导航应分为4列,对于平板电脑视图,导航应分为2列.这是一个嵌套的列表导航,因此使用<ul />围绕它构建了一个列.我的想法是,只需在1列中编写导航,然后使用jquery将其安排为4或2列动态.

I'm working on a responsive website with an navigation overlay (nodes and subnodes). The navigation should be split to 4 columns for desktop view or 2 columns for tablet view. It's a nested list navigation, so a column is build with <ul /> around it. My idea was, simply write the navigation in 1 column and arrange it to 4 or 2 cols dynamic with jquery.

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);

此解决方案将节点等分分成cols.不幸的是,这样看起来不太好:
http://bern09.ch/notgood.png

This solution splits the nodes in equal parts into the cols. Unfortunately it looks not really nice this way:
http://bern09.ch/notgood.png

我要实现的是一种具有几乎相同的列高的排列,如下所示:
http://bern09.ch/good.png

What i want to achieve is an arranging with almost the same column heights, like this:
http://bern09.ch/good.png

我必须以某种方式尊重子节点的数量,但是我真的不知道如何实现.也许任何人都有很好的建议,不胜感激.

I have to respect the number of subnodes in a way, but I don't really know how to achieve that. Maybe anyone has the great tip, a little help would be appreciated.

推荐答案

好.我懂了.这有点棘手.昨天我开始计算每一列的高度,但是我相信这种方法更加灵活:

Ok. I've got it. It was a little bit tricky. Last day I started out with calculating heights in every column, but I believe this approach is more flexible:

    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--;
        });
    });

这是一个概念.首先,我按其高度(从最高度到最低)对所有NODES进行排序,然后将它们附加到从左到右再返回的列(由maxCols指定)中.它不如您的漂亮,但是很遗憾打破了wrapAll的用法(我非常喜欢).我已经在进行一个小优化,它将使用threshold参数.当最短列和最长列之间的高度差大于阈值时,最长列的最后一个元素将移动到最短列.这样看起来应该更自然了.让我知道这是否是您要寻找的东西.

It's a concept. First I sort all the NODES by their height (from the heighest to the lowest) and then I append them to columns (specified by the maxCols) going from left to right and back. It's not as pretty as yours and unfortunately breaks wrapAll usage (I like it so much). I'm already working on a litte optimization which will use threshold parameter. When the difference in height between the shortest and the longest column is greater than threshold the last element of the longest column will be move to the shortest column. It should look more natural then. Let me know if this is what You are looking for.

这篇关于如何将嵌套导航拆分为高度几乎相等的列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆