HTML - 带有“更多”下拉列表的动态水平导航

时间:2011-11-15 19:15:24

标签: javascript html css

我必须实现一种在页面顶部调用水平导航栏的设计。此导航栏中可能包含未知数量的项目。如果酒吧用完房间,超限的链接将填入“更多”下拉列表。

视觉:

|page                                            |
|nav item 1   nav item 2    nav item 3   MORE v  |
|                                                |

在“更多”内,将有“导航项目4”和“导航项目5”。它会随屏幕尺寸而变化。

我的想法是使用JavaScript一次将链接移动到下拉列表,直到导航栏的边界框是可接受的大小。然而,随着屏幕闪烁和跨浏览器JS问题,这个想法让我成为一个悲伤的熊猫。有没有更好的办法?如果你遇到过这种事情的框架或纯粹的基于CSS的解决方案,或者不像我的想法那么严重的话,请告诉我。

与此同时,我会试着说服权力人士只使用下拉菜单,而不是在屏幕上出现不一致的情况。

3 个答案:

答案 0 :(得分:4)

http://jsfiddle.net/mblase75/cM7sU/

我知道你没有要求jQuery,但它使代码变得更短。但是,如果没有它,就没有任何东西可以做到。

您可以看到代码如何工作,希望 - 在菜单中向后循环,看看最后一项的垂直偏移是否与第一项的垂直偏移不同。如果是这样,将其推送到“更多”下拉菜单并继续循环;如果没有,突破循环。它包含在一个与window.resize事件和document.ready事件相关联的函数中。

显然,从功能方面来说,这段代码中有很多缺失,但它应该让你开始。

function shorterMenu() {
    $('#moreitems').children().unwrap().first().remove();
    $items = $('#menu div');
    $more = $('<div id="moreitems" class="menuitem"></div>');
    for (var i = $items.length; i--;) {
        $this = $items.eq(i);
        if ($this.offset().top > $items.eq(0).offset().top || $more.offset().top > $items.eq(0).offset().top) {
            $('#menu').append($more);
            $more.prepend($this);
        } else {
            i = 0; // end for
        }
    }
    if ($more.children().length) {
        $more.prepend('<div id="more" class="menuitem">More</div>');
    }
}
$(document).ready(shorterMenu);
$(window).resize(shorterMenu);

答案 1 :(得分:0)

对于任何需要它的人,我已使用香草javascript https://jsfiddle.net/xobea9cm/

从@Blazemonger重写了此方法的原始Jquery解决方案。
const parser = new DOMParser()

function dealWithMenu(menu) {
   let $items = menu.querySelectorAll('div')
   let $more = parser.parseFromString('<div class="more-items"></div>', 
      'text/html').body.firstChild

    for (var i = $items.length; i--;) {
        let $this = $items[i]

        if ($this.offsetTop > ($items[0]).offsetTop || $more.offsetTop > ($items[0]).offsetTop) {
            menu.appendChild($more)
            $more.insertBefore($this, $more.firstChild)
        } else {
            i = 0
        }
    }
    if ($more.children.length) {
         $more.insertBefore(
             parser.parseFromString('<div id="more" class="more-item menuitem">More</div>', 'text/html').body.firstChild,
             $more.firstChild)
    }
}

function shorterMenu() {
    const moreItems = document.querySelector('.more-items')

    const moreDivs = Array.from(document.querySelectorAll('.more-item'))

    moreDivs.forEach(moreDiv => moreDiv.remove())

    if (moreItems != undefined && moreItems.children && moreItems.children.length > 0) {
        Array.from(moreItems.children).forEach(child => moreItems.parentElement.appendChild(child))
        moreItems.remove()
    }

    const menus = Array.from(document.querySelectorAll('.menu'))

    menus.forEach(dealWithMenu)
}

let throttled = false
const delay = 100

shorterMenu()
window.addEventListener('resize', () => shorterMenu())

答案 2 :(得分:-1)

如果您需要更多的灵活性并且担心跨浏览器支持,那么这可以完全在css(google css下拉菜单中找到很多教程)中完成,然后Jquery可以很好地处理这类事情。

希望有所帮助。